赞
踩
大家好,给大家分享一下javascript高级程序设计 javascript权威指南,很多人还不知道这一点。下面详细解释一下。现在让我们来看看!
- // 1.数据属性 object.defineproperty(属相所在的对象,属性名,(4种))
- let person = {};
- Object.defineProperty(person, "name", {
- configurable: true, //表示能否通过delete删除属性从而重新定义属性,能否修改属性
- enumerable: true, //表示能否通过for-in循环返回属性
- writable: true, // 表示是否能修改属性的值
- value: "xujiang" // 属性的值
- })
- /* 在调用Object.defineProperty()方法创建一个新属性时,如不指定前三个属性字段,默认值都为false, 如果是修改已定义的属性时,则没有此限制 */
-
- // 2.访问器属性get/set
- let person = {name: "xujaijgn", year: 11};
- Object.defineProperty(person, "_name", {
- get: function(){
- return this.name
- },
- // 定义Set时,则设置一个属性的值时会导致其他属性发生变化
- set: function(newValue){
- this.name = newValue;
- this.year = 12;
- }
- })
-
- // 定义多个属性
- Object.defineProperties(book, {
- _year: {
- writable: false,
- value: 2001
- },
- year: {
- get: function(){
- return _year
- },
- set: function(newValue){
- this._year = newValue;
- }
- }
- })
- 原型理解:
- 1.isPrototypeOf()-------确认对象之间有没有原型关系
- 2.Object.getPrototypeOf()-------获取实例对象的原型
- 3.我们不能通过实例重写原型中的值,只能访问,并且如果实例和原型有相同的属性名,则会覆盖原型中的属性。
- 4.hasOwnProperty()-----检测一个属性是否在实例中
- 5.原型与in操作符:“name" in person:对象能访问到给定属性时返回true
- 6.Object.key(obj)---返回一个可以包含所有可枚举的属性
- 7.Object.getOwnPropertyNames() ---返回所有的实例属性,包括不可枚举的
- 8.实例中的指针只指向原型,而不是构造函数Python中的所有运算符号。 var person1=new Person() 那person1中的指针只指向Person.prototype 即 person1._proto_=Person.prototype
- 1.原型链的问题
- 1.包含引用类型值的原型属性会被所有实例共享,在通过原型实现继承时,原型实际上会变成另一个类型的实例,原先的实例属性变成了现在的原型属性。
- 2.在创建子类型的实例时,无法向父类构造函数传递参数
- function Parent(name){
- this.name=name;
- }
- function Child(){
- }
- Child.prototype=new Parent('zhangsan');
- var p=new Chlid();//构造出来子类的实例没有办法向父类传参。
- p.name;//可以继承父类的属性和方法
-
- 2.借用构造函数(在子类型构造函数的内部调用父类构造函数)
- //此时实例不会共享属性
- function Parent(name){
- this.colors = [1,3,4];
- this.name = name;
- }
- function Child(name){
- Parent.call(this, name);//但是实例化的子类能向父类传参。
- this.age = 12;
- }
- // 存在的问题: 1.函数无法复用 2.父类的原型对于子类是不可见的,子类不能继承原型上的属性和方法
-
- 3.组合继承(使用原型链继承原型属性和方法,使用借用构造继承实例属性) ---最常用的继承模式
- 缺点:无论如何都会调用两次父类构造函数
- // 父类
- function Parent(name){
- this.name = "xujaing";
- this.age = 12;
- };
- Parent.prototype.say = function() { console.log(this.age) };
- // 子类继承父类
- function Child(name){
- Parent.call(this, name);//1
- this.age = 13;
- }
- Child.prototype = new Parent();//2
- Child.prototype.constructor = Child;
- Child.prototype.say = function() { alert(this.age) };
-
- 4.原型式继承
- 实现1.
- function object(o){
- function F(){};
- F.prototype = o;
- return new F()
- }
- 实现2.通过Object.create(prototype, properties) // 第一个参数为创建新对象原型的对象,第二个参数为对新对象定义额外属性的对象(和defineProperties方法的第二个参数格式相同)
- A=Object.create(person, {//A._proto_=Person
- name: {
- value: "xujiang"
- }
- })
- 5.寄生组合式继承(通过借用构造函数继承属性,通过原型链混成的方式继承方法)---最理想的继承范式
- function inheritPrototype(sub,sup){
- let prototype = Object.create(sup.prototype);//prototype._proto_=sup.prototype
- prototype.constructor = sub;
- sub.prototype = prototype;
- }
-
- function Sup(){}
- Sup.prototype.say = function(){}
- function Sub(arg){
- // 关键
- Sup.call(this,arg);//var sub=new sup()
- }
- // 关键
- inheritPrototype(Sub, Sup);
闭包:可以访问定义它们的外部函数的参数和变量(除了this和arguments)。
闭包的优点:封装私有变量,形成块级作用域。
缺点:内存泄漏占用内存。
- function a(){
- let el = $("#el");
- let id = el.id;
- el.click(function(){
- alert(id)
- })
- // 清空dom,释放内存
- el = null;
- }
- Location对象:
- // location即是window对象的属性也是document对象的属性
- 1. hash // "#contents" 返回url的hash,如果不包含返回空
- 2. host // "www.wrox.com:80" 返回服务器名称和和端口号
- 3. hostname // "www.wrox.com" 返回不带端口号的服务器名称
- 4. href // 返回当前加载页面的完整url
- 5. pathname // "/a/" 返回url中的目录或文件名
- 6. port // "8080" 返回url中指定的端口号
- 7. protocol // "http" 返回页面使用的协议
- 8. search // "?q=java" 返回url中查询字符串,以问号开头
-
-
- navigator对象:
- navigator.language // "zh-CN" 浏览器的主语言
- navigator.appName // "Netscape" 完整的浏览器名称
- navigator.appVersion // 浏览器的版本
- // 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36
- navigator.cookieEnabled // true 表示cookie是否启用
- navigator.javaEnabled() // 表示浏览器是否启用java
- navigator.onLine // true 表示浏览器是否连接到了因特网
- navigator.platform // "Win32" 浏览器所在的系统平台
- navigator.userAgent // 浏览器用户代理字符串
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36"
- navigator.plugins // 检测浏览器中安装的插件的数组
- history对象:
- 1. history.go(0 | [123] | -1 | str) // 如果是Str,则会跳转到历史记录中包含该字符串的第一个位置
- 2. history.back() //后退一页
- 3. history.forward() //前进一页
- 4. history.length // 保存着历史纪录的数量
1.将对象转化成数组 Array.prototype.slice.apply(arguments,[0]);
2.将字符串转化成数组:str.split(’ ')//split转化成字符串数组
- 1.appendChild() //用于向childNodes末尾添加一个节点,返回新增的节点,如果节点已存在,那么就是从原来的位置移动到新位置
- 2.insertBefore() //将节点插入指定位置,接收两个参数,要插入的节点和作为参照的节点,返回插入的节点
- 3.replaceChild() //替换指定节点,接收2个参数,要插入的节点和要替换的节点,返回被移除的节点
- 4.removeChild() //移除节点,返回被移除的节点
- 5.cloneNode([true]) //参数为true,执行深复制,复制节点及整个子节点,为false时复制节点本身。cloneNode不会复制节点的java属性,但IE在此存在一个bug,所以建议在复制之前最好先移除事件处理程序
- document类型:
- 1. document的节点类型nodeType的值为9;
- 2. document.documentElement // 取得对<html>的引用
- 3. document.body // 取得对body的引用
- 4. document.title // 取得文章标题
- 5. document.title = "xxx" //设置文章标题
- 6. document.URL //取得完整的url
- 7. document.domain //取得域名
- 8. document.referrer //取得来源页面的url
- element类型:
- 1.nodeType值为:1
- 2.nodeName的值为元素标签名
- 3.tagName // 元素标签名,返回大写值,比较时一般采用 element.tagName.toLowerCase()
- 4.取得元素属性 getAttribute() / setAttribute() / removeAttribute()
- // 注:自定义属性通过点语法访问时会返回undefined
- 5.attributes // 获取元素的属性集合,访问方法: element.attributes[i].nodeName / element.attributes[i].nodeValue
- 6.创建元素 // document.createElement("div" | "<div class=\"box\">aaa</div>")
- 7.创建文本子节点 // document.createTextNode("Hello world")
offsetParent:获取元素的最近的具有定位属性(absolute或者relative)的父级元素。如果都没有则返回body
offsetHeight:元素在垂直方向上占用的空间大小。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。(不包括外边框margin)
offsetWidth:元素在水平方向上占用的空间大小。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度号右边框宽度。
offsetLeft:元素的左外边框至父元素的左内边框之间的像素距离。
offsetTop:元素的上外边框至父元素的上内边框之间的像素距离。
clientWidth:元素内容区宽度加上左右内边距宽度。可以通过document.body。clientWidth来获取浏览器视口的大小。
clientHeight:元素内容区高度加上上下内边距高度
scrollHeight:元素内容的实际总高度
scrollWidth:元素内容实际总宽度
scrollLeft:被隐藏的内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动的位置
scrollTop:被隐藏的内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置
- 1. 属性或方法
- type // 被触发的事件类型
- target // 事件的目标 触发事件的元素li
- currentTarget // 事件处理程序当前正在处理事件的那个元素 邦定事件的元素ul
- 注: 在事件处理程序内部,对象this始终等于currentTarget的值,而target只包含事件的实际目标
- *** 一个函数处理多个事件可以使用switch(event.type)的方式
- event.preventDefault() // 阻止事件的默认行为
- event.stopPropagation() // 阻止事件冒泡
- 1.鼠标和滚轮事件
- 1.客户区坐标位置clientX/clientY //表示事件发生时鼠标指针在视口中的水平和垂直位置
- 2.页面坐标位置 pageX/pageY //表示事件在页面中发生的位置
- 3.屏幕坐标位置 //获取事件发生时在屏幕中的位置
-
- 2.修改键(如果用户在触发事件时按下了shift/ctrl/alt/Meta,则返回true)
- event.shiftkey | event.altKey | event.metaKey | event.ctrlKey
-
- 3.鼠标按钮(event.button)
- // 对于mousedown和mouseup,其event中存在一个button属性,值为0表示主鼠标按钮,1表示中间鼠标按钮,2表示次鼠标按钮
-
- 4.鼠标滚轮事件(mousewheel)
- 1.兼容方案:
- let getWheelDelta = function(event){
- let wheelDelta = event.wheelDelta ? event.wheelDelta : (-event.detail * 40);
- return wheelDelta
- }
- *** 注:document在普通浏览器中通过mousewheel监听鼠标滚轮事件,在火狐中使用DOMMouseScroll监听
-
- 5.键盘与文本事件
- 6.变动事件
- 1.DOMSubtreeModified | DOMNodeInserted | DOMNodeRemoved
- *例子
- el.addEvent("DOMSubtreeModified", fn1)
-
- 7.HTML5事件
- 1.contextmenu事件(自定义上下文菜单)
- 2.DOMContentLoaded事件(在形成完整dom树之后就触发,不理会图像,js文件,css文件等资源是否下载完成)
- 3.hashchange事件(在URL的参数列表发生变化【即#号后面的所有字符串】时触发)
- 注:必须要把hashchange添加给window对象,event对象包含两个属性oldURL和newURL,分别保存着参数列表变化前后的完整URL vue的路由就是这个机制 通过haschange来监听url的变化,实现url改变但是不刷新页面的多页面的效果
- // 例子
- window.addEvent("hashchange", function(event){
- // oldURL和newURL存在兼容问题,最好用location.hash代替
- console.log(event.oldURL, event.newURL);
- })
当你卸载页面时,事件处理占用的内存没有释放。所以在卸载之前通过unonload事件移除所有事件的处理程序。并且不会保存在缓存中。
- // 源页面
- window.onload = function(){
- // 获取源页面iframe的内容window对象
- var iframeWindow = document.querySelector("#iframe").contentWindow;
- // 向iframe发送消息,并指定源的地址,两个参数必填
- iframeWindow.postMessage("xujiang", "http://127.0.0.1:5500");
-
- var mesWrap = document.querySelector(".mes-wrap");
- // 接收iframe传来的消息
- window.addEventListener("message",function(e){
- // alert(e.data);
- mesWrap.innerHTML = e.data;
- iframeWindow.postMessage("你叫什么?", "http://127.0.0.1:5500");
- },false);
- }
-
- // iframe页面,监听其他域传来的消息
- window.addEventListener("message",function(e){
- // 向发送消息的域反馈消息,event对象的属性如下:
- // data 传入的字符串数据
- // origin 发送消息的文档所在的域
- // source 发送消息的文档的window的代理
- e.source.postMessage("hello", "http://127.0.0.1:5500");
- },false);
- // ajax
- var xhr = new XMLHttpRequest(); // 创建xhr对象
-
- // 第一个方法:open(get | post等, "exam.php", false) 参数为请求类型,请求url,是否异步的boolean
- xhr.open("get","exam.php", false); // 调用该方法并不是真正的请求,而是请求一个请求以备发送
-
- // 发送真正的请求,接收一个参数,即作为请求主体要发送的数据,不发送数据时必须传递null,因为对于某些浏览器来说该参数是必须的
- xhr.send(null)
-
- // 检验响应的状态--->针对同步
- if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
- var data = xhr.responseText;
- }else{
- console.log(xhr.status);
- }
-
- // 异步方案
- xhr.onreadystatechange = function(){
- // xhr.readyStatus表示请求/响应过程的当前活动阶段
- // 0 未初始化,还没调用open()
- // 1 启动,已调用open()方法但未调用send()
- // 2 发送, 已调用send()方法,但未收到响应
- // 3 接收,已接收到部分响应数据
- // 4 完成,已接受到全部响应数据
- if(xhr.readyStatus == 4){
- if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
- var data = xhr.responseText;
- }else{
- console.log(xhr.status);
- }
- }
- }
- xhr.open("get","exam.php", false);
- xhr.send(null);
-
- // 在接收到响应之前还可以取消异步请求
- xhr.abort() // 在停止请求之后还应该进行解引用操作,防止内存堆积
-
- // 设置http请求头,必须放在open和send中间
- xhr.open("get","exam.php", false);
-
- xhr.setRequestHeader("accept", "application/json; charset=utf-8")
-
- xhr.send(null);
-
- // 获取响应头信息
- xhr.getResponseheader("accept");
- xhr.getAllResponseHeaders();
-
- // get请求:向现有url中添加查询字符串
- function addUrlParam(url, name, value){
- url += (url.indexOf("?") == -1 ? "?" : "&");
- url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
- }
-
- // post请求:模拟表单提交
- xhr.open("get","exam.php", false);
- // 设置提交时的内容类型
- xhr.setRequestHeader("content-Type", "application/x-www-form-urlencoded")
- // 假设表单form对象已获取
- xhr.send(serialize(form));
-
- // XHR2级 -- formData --序列化表单以及创建和表单格式相同的数据(用于通过xhr传输)
- var data = new FormData();
- data.append(key,value);
- // 也就可以用表单元素的数据预先填入数据
- var data = new FormData(document.forms[0]);
- //使用FormData的好处在于不必明确地在xhr上设置请求头部
- xhr.send(new FormData(form));
-
- // 进度事件
- loadStart/progress/error/abort/load
-
- // 跨域资源共享CORS
- 核心思想: 使用自定义的http头部让浏览器和服务器进行沟通,从而决定请求是成功还是失败
- 原理:
- 1.请求头指定源:Origin: http://www.baidu.com
- 2.如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部回发相同的源信息
- Access-Control-Allow-Origin:http://www.baidu.com
- (如果是公共资源,可以回发“*”)
- 3.如果没有这个头部,或者有这个头部但是源信息不匹配,浏览器就会驳回请求
-
- // 主流浏览器对cros的实现方式: 在url中使用绝对路径,但有限制:不能设置自定义头部,不能发送和接收cookie,获取不到getAllResponseHeaders()的返回值
-
- // 带凭据的请求
- withCredentials属性设置为true
- // 服务器接收到带凭据的请求后,会用下面的头部来请求,如果响应不包含这个头部,浏览器将不会把响应数据交给js
- Access-Control-Allow-Credentials: true
-
- // 跨浏览器的cros
- function createCORSRequest(method,url){
- var xhr = new XMLHttpRequest();
- if("withCredentials" in xhr){
- xhr.open(method,url,true);
- }else if(typeof XDomainRequest != "undefined"){
- xhr = new XDomainRequest();
- xhr.open(method,url);
- }else{
- xhr = null;
- }
- return xhr
- }
- var req = createCORSRequest("get","http://www.baidu.com/page/");
- if(req){
- req.onload = function(){
- // 对响应数据进行处理
- };
- req.send();
- }
- // 以上提供的公共方法有
- // abort() 用于停止正在进行的请求
- // onerror 用于替代onreadystatechange检验错误
- // onload 用于替代onreadystatechange检验成功
- // responseText 用于取得响应内容
- // send() 用于发送请求
-
- // 其他跨域技术
- 1.图像ping---常用于跟踪用户点击页面和动态广告曝光数,只能get请求
- var img = new Image();
- img.onload = img.onerror = function(){
- // 操作
- }
- img.src = "http://baidu.com?name=xujaing";
-
- 2.JSONP---可以直接访问响应文本,可以在浏览器和服务器之间进行双向通信,但有安全隐患
- function handleResponse(data){
- console.log(data);
- }
- var = document.createElement("");
- .src = "http://a.net/json/?callback=handleResponse";
- document.body.insertBefore(, document.body.firstChild);
-
- 3.Comet (服务器推送SSE)
- 常用的技术有长轮询和流
- 4.Web Sockets
- 1.Object.prototype.toString.call(value) == "[object Array]";//检测数据类型
- 2.//原生实现bind 柯理化思想
- //1.this 指向 apply /call2.参数形式 可以通过call(参数多)和apply实现(apply更方便)3.返回一个待执行的函数 闭包
- function testBind(that){
- var _this=this;
- var args=Array.prototype.slice.apply(arguments,[1]);//通过slice将arguments转换成数组,取得bind的除第一个参数以外的参数
- return function(){
- return _this.apply(that,args.concat(Array.prototype.slice.apply(arguments,[0])))
- }
-
- }
- //防抖
- function decouce(fn,wait){
- var timer=null;
- return function(){
- clearTimeout(timer);
- var timer=setTimeout(()=>{
- fn();
-
- },wait);
- }
- }
- //节流
- function throttle(fn,time,wait){
- var pre=null;
- var timer=null;
- var now=new Date();
- if(pre==undifined) pre=now;
- if(now-pre>time){
- clearTimeout(timer);
- fn();
- pre=now;
- }else{//小于time那么在wait内再执行一次
- clearTimeout(timer)
- timer=setTimerout(()=>{
- fn();
- },wait)
- }
- }
- (function(){
- function draw(timestamp){
- // 计算两次重绘的时间间隔
- var drawStart = (timestamp || Date.now()),
- diff = drawStart - startTime;
-
- // 使用diff确定下一步的绘制时间
-
- // 把startTime重写为这一次的绘制时间
- startTime = drawStart;
-
- // 重绘UI
- requestAnimationFrame(draw);
- }
-
- var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame,
- startTime = window.mozAnimationStartTime || Date.now();
- requestAnimationFrame(draw);
- })();
https://www.cnblogs.com/AI-fisher/p/11178130.html
https://zhuanlan.zhihu.com/p/84326290
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。