记住一句“内功”: 「对象.__proto __
=== 函数.prototype」
一. prototype
原型对象和__proto__
(1)每个实例对象都有一个__proto__
属性,指向其构造函数的prototype
原型对象。
(2)每个构造函数都有一个prototype
原型对象,其中prototype
原型对象的constructor指向构造函数本身。
关系图如下:
简单来说,实例对象的__proto__
指向构造函数的prototype
,prototype
原型对象相当于特定类型所有实例对象都可以访问的公共容器。
来看看代码:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
console.log(this.name);
}
var obj1 = new Person("Jason", 23);
var obj2 = new Person("Jack", 22);
obj1.sayName(); // "Jason"
obj2.sayName(); // "Jack"
obj1.__proto__ === Person.prototype // true
Person.prototype.__proto__ === Object.prototype // true
Person.prototype.constructor === Person // true
分析:首先我们创建了一个Person构造函数,并且在该构造函数的原型对象上加了一个sayName函数,通过这个构造函数创建了两个实例对象obj1,obj2,然后obj1和obj2两个实例对象使用Person原型对象上的sayName()函数。
接下来我们抽象一下,这几句话能解释一切关于原型方面的问题:
1.当 new 一个函数的时候会创建一个对象,「函数.prototype
」 等于 「被创建对象.__proto__
」。
2.一切函数都是由 Function 这个函数创建的,所以「Function.prototype
=== 被创建的函数.__proto__
」
3.一切函数的原型对象都是由 Object 这个函数创建的,所以「Object.prototype
=== 一切函数.prototype.__proto__
」
注意:Object函数也是Function函数创建的。
我们来看一段代码:
function People(){}
var p = new People()
p.__proto__ === People.prototype // true
People.__proto__ === Function.prototype // true
People.prototype.__proto__ === Object.prototype // true
分析:首先申明一个People构造函数,并且用这个构造函数创建一个实例对象p,由于p是构造函数People创建的,故p.__proto__
=== People.prototype
;由于People函数是由Function函数创建的,把Person函数当作对象,故People.__proto__
=== Function.prototype
;由于一切函数的原型对象都是由Object这个函数创建的,故People.prototype.__proto__
=== Object. prototype.
二. 原型链
我们首先来看一段代码:
var arr = [1,2,3];
arr.valueOf(); // [1, 2, 3];
上述代码中,就是申明了一个变量名为arr的数组,但是为啥会有valueOf()方法可以调用?
image.png
image.png
我们在arr的__proto__
中寻找,没有看到valueOf()函数。
image.png
然后我们接着在p.__proto__
.__protp__
中寻找,我们发现找到了valueOf()函数。
查找valueOf大致流程:
- 在实例对象arr中查找valueOf属性,找到返回。
- 没有找到,通过arr.
__proto__
,找到arr构造函数的prototype
并且查找上面的属性和方法,找到后返回。 - 没有找到,把Array.
prototype
当做obj,重复以上步骤。
当然不会一直找下去,原型链是有终点的,最后查找到Object.prototype
时
Object.prototype
.__proto__
=== null,意味着查找结束。
image.png
我们来看看上图的关系:
arr.__proto__ === Array.prototype //true
Array.prototype.__proto__ === Object.prototype //true
arr.__proto__.__proto__ === Object.prototype //true
// 原型链的终点
Object.prototype.__proto__ === null //true
原型链如下:
arr -> Array.prototype -> Object.prototype -> null
参考链接:
https://zhuanlan.zhihu.com/p/22473059
https://zhuanlan.zhihu.com/p/35790971
网友评论