当前位置:   article > 正文

javascript高级程序设计pdf,javascript 高级程序设计_javascript高级程序设计 pdf

javascript高级程序设计 pdf

大家好,给大家分享一下javascript高级程序设计 javascript权威指南,很多人还不知道这一点。下面详细解释一下。现在让我们来看看!

一、面向对象的程序设计

1. 属性类型
  1. // 1.数据属性 object.defineproperty(属相所在的对象,属性名,(4种))
  2. let person = {};
  3. Object.defineProperty(person, "name", {
  4. configurable: true, //表示能否通过delete删除属性从而重新定义属性,能否修改属性
  5. enumerable: true, //表示能否通过for-in循环返回属性
  6. writable: true, // 表示是否能修改属性的值
  7. value: "xujiang" // 属性的值
  8. })
  9. /* 在调用Object.defineProperty()方法创建一个新属性时,如不指定前三个属性字段,默认值都为false, 如果是修改已定义的属性时,则没有此限制 */
  10. // 2.访问器属性get/set
  11. let person = {name: "xujaijgn", year: 11};
  12. Object.defineProperty(person, "_name", {
  13. get: function(){
  14. return this.name
  15. },
  16. // 定义Set时,则设置一个属性的值时会导致其他属性发生变化
  17. set: function(newValue){
  18. this.name = newValue;
  19. this.year = 12;
  20. }
  21. })
  22. // 定义多个属性
  23. Object.defineProperties(book, {
  24. _year: {
  25. writable: false,
  26. value: 2001
  27. },
  28. year: {
  29. get: function(){
  30. return _year
  31. },
  32. set: function(newValue){
  33. this._year = newValue;
  34. }
  35. }
  36. })
2.创建对象
  1. 原型理解:
  2. 1.isPrototypeOf()-------确认对象之间有没有原型关系
  3. 2.Object.getPrototypeOf()-------获取实例对象的原型
  4. 3.我们不能通过实例重写原型中的值,只能访问,并且如果实例和原型有相同的属性名,则会覆盖原型中的属性。
  5. 4.hasOwnProperty()-----检测一个属性是否在实例中
  6. 5.原型与in操作符:“name" in person:对象能访问到给定属性时返回true
  7. 6.Object.key(obj)---返回一个可以包含所有可枚举的属性
  8. 7.Object.getOwnPropertyNames() ---返回所有的实例属性,包括不可枚举的
  9. 8.实例中的指针只指向原型,而不是构造函数Python中的所有运算符号。 var person1=new Person() 那person1中的指针只指向Person.prototype 即 person1._proto_=Person.prototype
  1. 组合(构造函数模式和原型模式):用构造函数定义实例属性,用原型定义方法和共享属性。
3.继承
  1. 1.原型链的问题
  2. 1.包含引用类型值的原型属性会被所有实例共享,在通过原型实现继承时,原型实际上会变成另一个类型的实例,原先的实例属性变成了现在的原型属性。
  3. 2.在创建子类型的实例时,无法向父类构造函数传递参数
  4. function Parent(name){
  5. this.name=name;
  6. }
  7. function Child(){
  8. }
  9. Child.prototype=new Parent('zhangsan');
  10. var p=new Chlid();//构造出来子类的实例没有办法向父类传参。
  11. p.name;//可以继承父类的属性和方法
  12. 2.借用构造函数(在子类型构造函数的内部调用父类构造函数)
  13. //此时实例不会共享属性
  14. function Parent(name){
  15. this.colors = [1,3,4];
  16. this.name = name;
  17. }
  18. function Child(name){
  19. Parent.call(this, name);//但是实例化的子类能向父类传参。
  20. this.age = 12;
  21. }
  22. // 存在的问题: 1.函数无法复用 2.父类的原型对于子类是不可见的,子类不能继承原型上的属性和方法
  23. 3.组合继承(使用原型链继承原型属性和方法,使用借用构造继承实例属性) ---最常用的继承模式
  24. 缺点:无论如何都会调用两次父类构造函数
  25. // 父类
  26. function Parent(name){
  27. this.name = "xujaing";
  28. this.age = 12;
  29. };
  30. Parent.prototype.say = function() { console.log(this.age) };
  31. // 子类继承父类
  32. function Child(name){
  33. Parent.call(this, name);//1
  34. this.age = 13;
  35. }
  36. Child.prototype = new Parent();//2
  37. Child.prototype.constructor = Child;
  38. Child.prototype.say = function() { alert(this.age) };
  39. 4.原型式继承
  40. 实现1.
  41. function object(o){
  42. function F(){};
  43. F.prototype = o;
  44. return new F()
  45. }
  46. 实现2.通过Object.create(prototype, properties) // 第一个参数为创建新对象原型的对象,第二个参数为对新对象定义额外属性的对象(和defineProperties方法的第二个参数格式相同)
  47. A=Object.create(person, {//A._proto_=Person
  48. name: {
  49. value: "xujiang"
  50. }
  51. })
  52. 5.寄生组合式继承(通过借用构造函数继承属性,通过原型链混成的方式继承方法)---最理想的继承范式
  53. function inheritPrototype(sub,sup){
  54. let prototype = Object.create(sup.prototype);//prototype._proto_=sup.prototype
  55. prototype.constructor = sub;
  56. sub.prototype = prototype;
  57. }
  58. function Sup(){}
  59. Sup.prototype.say = function(){}
  60. function Sub(arg){
  61. // 关键
  62. Sup.call(this,arg);//var sub=new sup()
  63. }
  64. // 关键
  65. inheritPrototype(Sub, Sup);

二、函数表达式

闭包与变量

闭包:可以访问定义它们的外部函数的参数和变量(除了this和arguments)。
闭包的优点:封装私有变量,形成块级作用域。
缺点:内存泄漏占用内存。

  1. function a(){
  2. let el = $("#el");
  3. let id = el.id;
  4. el.click(function(){
  5. alert(id)
  6. })
  7. // 清空dom,释放内存
  8. el = null;
  9. }

三、BOM对象

  1. Location对象:
  2. // location即是window对象的属性也是document对象的属性
  3. 1. hash // "#contents" 返回url的hash,如果不包含返回空
  4. 2. host // "www.wrox.com:80" 返回服务器名称和和端口号
  5. 3. hostname // "www.wrox.com" 返回不带端口号的服务器名称
  6. 4. href // 返回当前加载页面的完整url
  7. 5. pathname // "/a/" 返回url中的目录或文件名
  8. 6. port // "8080" 返回url中指定的端口号
  9. 7. protocol // "http" 返回页面使用的协议
  10. 8. search // "?q=java" 返回url中查询字符串,以问号开头
  11. navigator对象:
  12. navigator.language // "zh-CN" 浏览器的主语言
  13. navigator.appName // "Netscape" 完整的浏览器名称
  14. navigator.appVersion // 浏览器的版本
  15. // 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36
  16. navigator.cookieEnabled // true 表示cookie是否启用
  17. navigator.javaEnabled() // 表示浏览器是否启用java
  18. navigator.onLine // true 表示浏览器是否连接到了因特网
  19. navigator.platform // "Win32" 浏览器所在的系统平台
  20. navigator.userAgent // 浏览器用户代理字符串
  21. // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36"
  22. navigator.plugins // 检测浏览器中安装的插件的数组
  23. history对象:
  24. 1. history.go(0 | [123] | -1 | str) // 如果是Str,则会跳转到历史记录中包含该字符串的第一个位置
  25. 2. history.back() //后退一页
  26. 3. history.forward() //前进一页
  27. 4. history.length // 保存着历史纪录的数量

四、DOM对象

1.将对象转化成数组 Array.prototype.slice.apply(arguments,[0]);
2.将字符串转化成数组:str.split(’ ')//split转化成字符串数组

  1. 1.appendChild() //用于向childNodes末尾添加一个节点,返回新增的节点,如果节点已存在,那么就是从原来的位置移动到新位置
  2. 2.insertBefore() //将节点插入指定位置,接收两个参数,要插入的节点和作为参照的节点,返回插入的节点
  3. 3.replaceChild() //替换指定节点,接收2个参数,要插入的节点和要替换的节点,返回被移除的节点
  4. 4.removeChild() //移除节点,返回被移除的节点
  5. 5.cloneNode([true]) //参数为true,执行深复制,复制节点及整个子节点,为false时复制节点本身。cloneNode不会复制节点的java属性,但IE在此存在一个bug,所以建议在复制之前最好先移除事件处理程序
  1. document类型:
  2. 1. document的节点类型nodeType的值为9
  3. 2. document.documentElement // 取得对<html>的引用
  4. 3. document.body // 取得对body的引用
  5. 4. document.title // 取得文章标题
  6. 5. document.title = "xxx" //设置文章标题
  7. 6. document.URL //取得完整的url
  8. 7. document.domain //取得域名
  9. 8. document.referrer //取得来源页面的url
  1. element类型:
  2. 1.nodeType值为:1
  3. 2.nodeName的值为元素标签名
  4. 3.tagName // 元素标签名,返回大写值,比较时一般采用 element.tagName.toLowerCase()
  5. 4.取得元素属性 getAttribute() / setAttribute() / removeAttribute()
  6. // 注:自定义属性通过点语法访问时会返回undefined
  7. 5.attributes // 获取元素的属性集合,访问方法: element.attributes[i].nodeName / element.attributes[i].nodeValue
  8. 6.创建元素 // document.createElement("div" | "<div class=\"box\">aaa</div>")
  9. 7.创建文本子节点 // document.createTextNode("Hello world")

五、元素大小

1.偏移量

offsetParent:获取元素的最近的具有定位属性(absolute或者relative)的父级元素。如果都没有则返回body
offsetHeight:元素在垂直方向上占用的空间大小。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。(不包括外边框margin)
offsetWidth:元素在水平方向上占用的空间大小。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度号右边框宽度。
offsetLeft:元素的左外边框至父元素的左内边框之间的像素距离。
offsetTop:元素的上外边框至父元素的上内边框之间的像素距离。
偏移量

2.客户区的大小

clientWidth:元素内容区宽度加上左右内边距宽度。可以通过document.body。clientWidth来获取浏览器视口的大小。
clientHeight:元素内容区高度加上上下内边距高度
在这里插入图片描述

3.滑动大小

scrollHeight:元素内容的实际总高度
scrollWidth:元素内容实际总宽度
scrollLeft:被隐藏的内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动的位置
scrollTop:被隐藏的内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置
在这里插入图片描述

六、事件

1.事件对象event
  1. 1. 属性或方法
  2. type // 被触发的事件类型
  3. target // 事件的目标 触发事件的元素li
  4. currentTarget // 事件处理程序当前正在处理事件的那个元素 邦定事件的元素ul
  5. 注: 在事件处理程序内部,对象this始终等于currentTarget的值,而target只包含事件的实际目标
  6. *** 一个函数处理多个事件可以使用switch(event.type)的方式
  7. event.preventDefault() // 阻止事件的默认行为
  8. event.stopPropagation() // 阻止事件冒泡
2.事件类型
  1. 1.鼠标和滚轮事件
  2. 1.客户区坐标位置clientX/clientY //表示事件发生时鼠标指针在视口中的水平和垂直位置
  3. 2.页面坐标位置 pageX/pageY //表示事件在页面中发生的位置
  4. 3.屏幕坐标位置 //获取事件发生时在屏幕中的位置
  5. 2.修改键(如果用户在触发事件时按下了shift/ctrl/alt/Meta,则返回true)
  6. event.shiftkey | event.altKey | event.metaKey | event.ctrlKey
  7. 3.鼠标按钮(event.button)
  8. // 对于mousedown和mouseup,其event中存在一个button属性,值为0表示主鼠标按钮,1表示中间鼠标按钮,2表示次鼠标按钮
  9. 4.鼠标滚轮事件(mousewheel)
  10. 1.兼容方案:
  11. let getWheelDelta = function(event){
  12. let wheelDelta = event.wheelDelta ? event.wheelDelta : (-event.detail * 40);
  13. return wheelDelta
  14. }
  15. *** 注:document在普通浏览器中通过mousewheel监听鼠标滚轮事件,在火狐中使用DOMMouseScroll监听
  16. 5.键盘与文本事件
  17. 6.变动事件
  18. 1.DOMSubtreeModified | DOMNodeInserted | DOMNodeRemoved
  19. *例子
  20. el.addEvent("DOMSubtreeModified", fn1)
  21. 7.HTML5事件
  22. 1.contextmenu事件(自定义上下文菜单)
  23. 2.DOMContentLoaded事件(在形成完整dom树之后就触发,不理会图像,js文件,css文件等资源是否下载完成)
  24. 3.hashchange事件(在URL的参数列表发生变化【即#号后面的所有字符串】时触发)
  25. 注:必须要把hashchange添加给window对象,event对象包含两个属性oldURL和newURL,分别保存着参数列表变化前后的完整URL vue的路由就是这个机制 通过haschange来监听url的变化,实现url改变但是不刷新页面的多页面的效果
  26. // 例子
  27. window.addEvent("hashchange", function(event){
  28. // oldURL和newURL存在兼容问题,最好用location.hash代替
  29. console.log(event.oldURL, event.newURL);
  30. })
3.性能问题

当你卸载页面时,事件处理占用的内存没有释放。所以在卸载之前通过unonload事件移除所有事件的处理程序。并且不会保存在缓存中。

七、跨域文档传递iframe

  1. // 源页面
  2. window.onload = function(){
  3. // 获取源页面iframe的内容window对象
  4. var iframeWindow = document.querySelector("#iframe").contentWindow;
  5. // 向iframe发送消息,并指定源的地址,两个参数必填
  6. iframeWindow.postMessage("xujiang", "http://127.0.0.1:5500");
  7. var mesWrap = document.querySelector(".mes-wrap");
  8. // 接收iframe传来的消息
  9. window.addEventListener("message",function(e){
  10. // alert(e.data);
  11. mesWrap.innerHTML = e.data;
  12. iframeWindow.postMessage("你叫什么?", "http://127.0.0.1:5500");
  13. },false);
  14. }
  15. // iframe页面,监听其他域传来的消息
  16. window.addEventListener("message",function(e){
  17. // 向发送消息的域反馈消息,event对象的属性如下:
  18. // data 传入的字符串数据
  19. // origin 发送消息的文档所在的域
  20. // source 发送消息的文档的window的代理
  21. e.source.postMessage("hello", "http://127.0.0.1:5500");
  22. },false);

八、ajax和cors

  1. // ajax
  2. var xhr = new XMLHttpRequest(); // 创建xhr对象
  3. // 第一个方法:open(get | post等, "exam.php", false) 参数为请求类型,请求url,是否异步的boolean
  4. xhr.open("get","exam.php", false); // 调用该方法并不是真正的请求,而是请求一个请求以备发送
  5. // 发送真正的请求,接收一个参数,即作为请求主体要发送的数据,不发送数据时必须传递null,因为对于某些浏览器来说该参数是必须的
  6. xhr.send(null)
  7. // 检验响应的状态--->针对同步
  8. if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
  9. var data = xhr.responseText;
  10. }else{
  11. console.log(xhr.status);
  12. }
  13. // 异步方案
  14. xhr.onreadystatechange = function(){
  15. // xhr.readyStatus表示请求/响应过程的当前活动阶段
  16. // 0 未初始化,还没调用open()
  17. // 1 启动,已调用open()方法但未调用send()
  18. // 2 发送, 已调用send()方法,但未收到响应
  19. // 3 接收,已接收到部分响应数据
  20. // 4 完成,已接受到全部响应数据
  21. if(xhr.readyStatus == 4){
  22. if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
  23. var data = xhr.responseText;
  24. }else{
  25. console.log(xhr.status);
  26. }
  27. }
  28. }
  29. xhr.open("get","exam.php", false);
  30. xhr.send(null);
  31. // 在接收到响应之前还可以取消异步请求
  32. xhr.abort() // 在停止请求之后还应该进行解引用操作,防止内存堆积
  33. // 设置http请求头,必须放在open和send中间
  34. xhr.open("get","exam.php", false);
  35. xhr.setRequestHeader("accept", "application/json; charset=utf-8")
  36. xhr.send(null);
  37. // 获取响应头信息
  38. xhr.getResponseheader("accept");
  39. xhr.getAllResponseHeaders();
  40. // get请求:向现有url中添加查询字符串
  41. function addUrlParam(url, name, value){
  42. url += (url.indexOf("?") == -1 ? "?" : "&");
  43. url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
  44. }
  45. // post请求:模拟表单提交
  46. xhr.open("get","exam.php", false);
  47. // 设置提交时的内容类型
  48. xhr.setRequestHeader("content-Type", "application/x-www-form-urlencoded")
  49. // 假设表单form对象已获取
  50. xhr.send(serialize(form));
  51. // XHR2级 -- formData --序列化表单以及创建和表单格式相同的数据(用于通过xhr传输)
  52. var data = new FormData();
  53. data.append(key,value);
  54. // 也就可以用表单元素的数据预先填入数据
  55. var data = new FormData(document.forms[0]);
  56. //使用FormData的好处在于不必明确地在xhr上设置请求头部
  57. xhr.send(new FormData(form));
  58. // 进度事件
  59. loadStart/progress/error/abort/load
  60. // 跨域资源共享CORS
  61. 核心思想: 使用自定义的http头部让浏览器和服务器进行沟通,从而决定请求是成功还是失败
  62. 原理:
  63. 1.请求头指定源:Origin: http://www.baidu.com
  64. 2.如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部回发相同的源信息
  65. Access-Control-Allow-Origin:http://www.baidu.com
  66. (如果是公共资源,可以回发“*”)
  67. 3.如果没有这个头部,或者有这个头部但是源信息不匹配,浏览器就会驳回请求
  68. // 主流浏览器对cros的实现方式: 在url中使用绝对路径,但有限制:不能设置自定义头部,不能发送和接收cookie,获取不到getAllResponseHeaders()的返回值
  69. // 带凭据的请求
  70. withCredentials属性设置为true
  71. // 服务器接收到带凭据的请求后,会用下面的头部来请求,如果响应不包含这个头部,浏览器将不会把响应数据交给js
  72. Access-Control-Allow-Credentials: true
  73. // 跨浏览器的cros
  74. function createCORSRequest(method,url){
  75. var xhr = new XMLHttpRequest();
  76. if("withCredentials" in xhr){
  77. xhr.open(method,url,true);
  78. }else if(typeof XDomainRequest != "undefined"){
  79. xhr = new XDomainRequest();
  80. xhr.open(method,url);
  81. }else{
  82. xhr = null;
  83. }
  84. return xhr
  85. }
  86. var req = createCORSRequest("get","http://www.baidu.com/page/");
  87. if(req){
  88. req.onload = function(){
  89. // 对响应数据进行处理
  90. };
  91. req.send();
  92. }
  93. // 以上提供的公共方法有
  94. // abort() 用于停止正在进行的请求
  95. // onerror 用于替代onreadystatechange检验错误
  96. // onload 用于替代onreadystatechange检验成功
  97. // responseText 用于取得响应内容
  98. // send() 用于发送请求
  99. // 其他跨域技术
  100. 1.图像ping---常用于跟踪用户点击页面和动态广告曝光数,只能get请求
  101. var img = new Image();
  102. img.onload = img.onerror = function(){
  103. // 操作
  104. }
  105. img.src = "http://baidu.com?name=xujaing";
  106. 2.JSONP---可以直接访问响应文本,可以在浏览器和服务器之间进行双向通信,但有安全隐患
  107. function handleResponse(data){
  108. console.log(data);
  109. }
  110. var = document.createElement("");
  111. .src = "http://a.net/json/?callback=handleResponse";
  112. document.body.insertBefore(, document.body.firstChild);
  113. 3.Comet (服务器推送SSE)
  114. 常用的技术有长轮询和流
  115. 4.Web Sockets

九、高级技巧

1.高级函数
  1. 1.Object.prototype.toString.call(value) == "[object Array]";//检测数据类型
  2. 2.//原生实现bind 柯理化思想
  3. //1.this 指向 apply /call2.参数形式 可以通过call(参数多)和apply实现(apply更方便)3.返回一个待执行的函数 闭包
  4. function testBind(that){
  5. var _this=this;
  6. var args=Array.prototype.slice.apply(arguments,[1]);//通过slice将arguments转换成数组,取得bind的除第一个参数以外的参数
  7. return function(){
  8. return _this.apply(that,args.concat(Array.prototype.slice.apply(arguments,[0])))
  9. }
  10. }
2.高级定时器
  1. //防抖
  2. function decouce(fn,wait){
  3. var timer=null;
  4. return function(){
  5. clearTimeout(timer);
  6. var timer=setTimeout(()=>{
  7. fn();
  8. },wait);
  9. }
  10. }
  11. //节流
  12. function throttle(fn,time,wait){
  13. var pre=null;
  14. var timer=null;
  15. var now=new Date();
  16. if(pre==undifined) pre=now;
  17. if(now-pre>time){
  18. clearTimeout(timer);
  19. fn();
  20. pre=now;
  21. }else{//小于time那么在wait内再执行一次
  22. clearTimeout(timer)
  23. timer=setTimerout(()=>{
  24. fn();
  25. },wait)
  26. }
  27. }

十、新的API

1.requestAnimationFrame():计时器不需要设置时间间隔,比其他两种精准
  1. (function(){
  2. function draw(timestamp){
  3. // 计算两次重绘的时间间隔
  4. var drawStart = (timestamp || Date.now()),
  5. diff = drawStart - startTime;
  6. // 使用diff确定下一步的绘制时间
  7. // 把startTime重写为这一次的绘制时间
  8. startTime = drawStart;
  9. // 重绘UI
  10. requestAnimationFrame(draw);
  11. }
  12. var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame,
  13. startTime = window.mozAnimationStartTime || Date.now();
  14. requestAnimationFrame(draw);
  15. })();

https://www.cnblogs.com/AI-fisher/p/11178130.html
https://zhuanlan.zhihu.com/p/84326290

文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树首页概览435628 人正在系统学习中
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/871219
推荐阅读
相关标签
  

闽ICP备14008679号