原型
prototype
定义:是function对象的一个属性,它定义了构造函数构造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法。
【注】:
(1) 原型也是一个对象
(2) 不能通过构造出的实例去更改原型的属性
(3) 每一个function对象都会自带一个prototype属性以及一个proto属性
(4) 每一个对象都会自带一个proto属性
__proto__
原型作为对象的内部属性,是不能被直接访问的,所以,部分浏览器提供“proto”的访问器去访问原型。其中实例的proto和构造函数的原型完全相等。如下代码所示:
1 | function Car(){ |
关系图如下:
constructor
constructor是原型的一个属性,指向关联的构造函数。如下代码所示:
1 | function Car(){ |
关系图如下:
用法:1.将公有元素保存到原型里面
实例1:
1 | function Car(color,owner){ |
上面的代码每次执行都会去执行流程化生产的属性,例如carName,height等,造成代码冗余,解决这个问题,将共有代码提到原型里面,原型只需要加载一次,不用每次执行都去加载,然后根据原型继承,可在实例中使用。改造后的代码如下:
1 | Car.prototype.carName = "BMW"; |
原型链
1 | Grand.prototype.name = "hedy" |
如上代码中,当打印son.name时,在Son自己的构造方法里面是找不到name属性的,然后就顺着son.proto,也就是Father.prototype中去查找,自然找到并打印judy,此时,可以看到在代码中Grand原型里面也有一个name属性,但是js查找过程是就近原则,最先找到谁就是谁,后面不会再去查找。
不难看出,son,father以及grand之间是通过proto去连接的,查找的时候也是根据这个属性一级一级往上查找。
关系图如下:
如上图所示,此处只画了grand到object两个阶段,可以看到该条原型链最终指向的是null,因此,该原型链的终端就是object.prototype。
提问:是否所有对象最终都会继承自Object.prototype。答:不是,有特例。当使用Object.create()创建一个具有指定原型且可选择性的包含指定属性的对象,可传两个参数,第一个是prototyoe,必须,可以是null;第二个参数是可选的。
当传入的第一个参数是null时,返回回来的对象是没有原型的,所以它不存在继承自Object.prototype.
如此下图所示:
原型陷阱
1 | Person.prototype.name = "sunny"; |
当对原型对象执行完全替换的时候,可能会触发原型链中的某种异常,并且当重写了某对象的prototype时,该对象原型的constructor指向的是Object而不是Person,因此,当重写了某对象的prototype时,需要重置一下constructor方法,即Person.prototype.constructor = Person.
Ajax
定义:相当浏览器和服务器的中间层,其中最重要的是对象XMLHttpRequest对象。
状态(readyState):分为以下5种:
① 0:未初始化状态(此时刚创建XMLHttpRequest实例)
② 1:启动状态(此时调用open方法)
③ 2:发送状态(调用send方法,但此时已经有部分数据被接收)
④ 3: 接收状态(对数据进行接收及处理)
⑤ 4:完全接收数据并完成数据的处理
方法
(1) onreadystatechange:该方法会在readystate的状态改变时触发。
(2) open(method,url,true/false):强调第三个参数,主要是同步和异步的控制,默认是true,异步方式。
(3) send():参数格式:null,xml,.txt
(4) setRequestHeader():发送时可设置请求头
(5) getResponsHeader():接收响应数据
(6) overrideMimeType():决定内容用什么形式显示
(7) onloadend():error时触发或者调abort时主动触发或者请求完成时触发
(8) post:载体:http键值对形式,以form形式提交
(9)get:载体:直接在http中
封装
1.axios(原理参照promise)
特性:(1) 拦截请求并响应
(2) 自动转换json格式
(3) 客户端支持跨域伪造
(4) axios.get(url,配置,数据).then
(5) 并发请求
2.fetch