0%

关于原型链

以下这张图,基本解释了所有的原型关系

image.png

核心要素是:

1
2
3
4
5
var Foo = function (){}
var foo = new Foo()
foo.__proto__ == foo.constructor.prototype == Foo.prototype

// .__proto__ 可以简单理解成 .construstor.prototype 的简写

但本质上__proto__不等于.constructor.prototype,当我把对象的constructor置为null.__proto__还是能够读到,但是.constructor.prototype直接报错了。这里这么说只是为了方便理解

说到底.__proto__就是这个对象的构造函数的原型。

理解了这个就能理解上面图示的所有的关系了。


以下有助于理解几个基类之间的关系

instanceof操作符

instanceof的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例。它的内部实现原理是这样的:

1
2
3
4
//设 L instanceof R 
//通过判断
L.__proto__.__proto__ ..... === R.prototype ?
//最终返回true or false

也就是沿着L的__proto__一直寻找到原型链末端,直到等于R.prototype为止。知道了这个也就知道为什么以下这些奇怪的表达式为什么会得到相应的值了

1
2
3
4
5
Function instanceof Object // true 
Object instanceof Function // true
Function instanceof Function //true
Object instanceof Object // true
Number instanceof Number //false

总结了下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Object.constructor === function Function (){} // true
Function.constructor === function Function (){} // true

// 两个需要特殊注意一下, 记住这个基本上能把所有的东西都推理出来了。

Function.prototype === functoin (){ native code } // true

Function.prototype.constructor === Funtion // true

Function.prototype.constructor.prototype === function (){ native code } // true

// ...无限循环

Function.prototype.__proto__ === Object.prototype // true

Object.prototype.__proto__ === null // 原型链的终点

关于__proto__

__proto__ 是内部的构造函数原型对象, 一般情况下

1
obj.__proto__ === obj.constructor.prototype // true

但是__proto__不会因为你在对象的prototype中更改constructor而改变。它总是指向对象被创建时的那个constructor function , 举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Animal(){}

function Dog(){}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog; // 在继承的时候,这里改变了prototype.constructor,但是不影响__proto__的结果

// 完成继承

new Dog() instanceof Animal // true
new Dog() instanceof Dog // true

// 根据以上 instanceof 的原理

new Dog().__proto__.__proto__ === Animal.prototype // true

// 在这里__proto__和constructor.prototype的结果就不同, 一定要搞清楚

new Dog().__proto__.constructor.prototype === Animal.prototype // false
new Dog().__proto__.constructor.prototype === Dog.prototype // true

部分内容摘自

作者:苏墨橘

链接:https://www.zhihu.com/question/34183746/answer/59043879