web前端:理解js原型链

JavaScript06

web前端:理解js原型链,第1张

工具/材料

javascript

01

学习原型链之前我们先认识一下构造函数,代码如下:

function S() {

this.name = 'xxx'

this.say = function() { console.log(this.name) }

}

var s1 = new S()

其中,s1是S的实例,s1的__proto__(大家先不用管__proto__属性,后续会讲到)中有一个constructor(构造函数)属性,该属性指向S。

在这里,大家可以记住两点:

1.s1是构造函数S的实例;

2.s1.__proto__.constructor===S 也可以写成 s1.constructor===S

02

接下来我们来看下一段代码:

function S2() {}

S2.prototype.name = 'XXX'

S2.prototype.say = function() {

console.log(this.name)

}

var s2 = new S2()

var s3 = new S2()

console.log(s2.sayName === s3.sayName)//true

console.log(s2.__proto__===S2.prototype)//true

这一段代码中我们可以看到一个新属性——prototype,这是什么呢,其实这就是构造函数S2的原型对象,每个对象都有__proto__属性,但是只有函数对象才有prototype属性。而s2是构造函数S2的实例,而s2.__proto__指向的就是S2的原型对象,即s2.__proto__===S2.prototype。得到一个结论,实例的__proto__属性指向的就是其构造函数的原型对象。

03

继续上一步的代码,我们添加代码继续调试:

console.log(s2.__proto__)//返回S2的原型对象

console.log(S2.prototype)//返回S2的原型对象

console.log(s2.__proto__.__proto__)//返回Object对象

console.log(S2.prototype.__proto__)//返回Object对象

console.log(s2.__proto__.__proto__.__proto__)//返回null

console.log(S2.prototype.__proto__.__proto__)//返回null

其实,S2的原型对象上还有原型对象,因为S2的原型对象也相当于只是Object对象的一个实例。

04

在这里我给大家画了一张图,便于大家理解原型链。

特别提示

码子不易,我如有说得不对的地方,望大家指点包含,谢谢

Object() Function() Array() 等等都为构造函数。

Js 面向对象与传统oop 有些不同,语法较高级 语法糖封装。

This 为指针。指向this作用域的调用者

1.原型继承链顶端为Object 。Js函数是对象

2.当读取对象中的属性时,先去实例本身中搜索,如搜索不到则去指向的原型中搜索

1.原型的存在意义在于实现继承共享,是在构造函数中定义的一个成员对象,在下次实例化时不需要在构造函数中定义成员 就可实现实例共享方法属性。

例子:通常为。构造函数.prototype.xxx=我想实现实例继承的东西 -》 new 构造函数 -》新实例a对象.原型指针指向构造函数的xxx对象(引用类型)

例子:Array 不等于 Array() 原因 Array为一个函数,而Array()为一个构造函数调用语句,故Array拥有prototype对象用于实例的共享继承,Array()产生一个实例 故只能拥有prototype对象的私有指针 proto

2.在使用原型继承时 不能使用字面量 构造函数.prototype={} 的方式重写原型对象 。因为会导致该原型对象的constructor属性被重写,在生成的实例中导致constructor指向Object并且会切断之前原型对象的联系,破坏原型链。

3.JavaScript 主要通过原型链实现继承。原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的

例子:

xxx实例. proto -》function xxx()构造函数.prototype对象故xxx. proto === xxx.prototype

xxx.prototype. proto -》Object.prototype因为所有对象都为Object函数构造来的。故xxx.prototype. proto ===Object.prototype。

Object.prototype. proto 为原型链顶端 proto 定义了尚未使用所以为null故Object.prototype. proto ===null约定俗成。

instanceof 用来判断某实例是否为某构造函数的实例

isPrototypeOf 用于判断某实例是否拥有某构造函数的原型对象指针

1.原型模式有忽略构造函数定义初始值步骤及原型中操作引用类型的缺点。

所以需要组合使用 构造函数模式+原型模式 来创建实例。在构造函数中定义实例的属性,而需共享的方法就定义在原型对象中。

继承:在子构造函数中调用 父.call(this, name)实现构造函数之间的属性继承。使用 子.prototype = new 父()子.prototype.constructor = 子实现方法的继承。

2.如要在生产环境下的构造函数新增方法(如Array) 需要使用一个类似于工厂函数的寄生构造函数模式 在构造函数中返回一个修改后的对象