美文网首页饥人谷技术博客
浅析原型和原型链

浅析原型和原型链

作者: Jason_Shu | 来源:发表于2018-09-17 14:37 被阅读15次

记住一句“内功”: 「对象.__proto __ === 函数.prototype」

一. prototype原型对象和__proto__
(1)每个实例对象都有一个__proto__属性,指向其构造函数的prototype原型对象。
(2)每个构造函数都有一个prototype原型对象,其中prototype原型对象的constructor指向构造函数本身。
关系图如下:

image.png

简单来说,实例对象的__proto__指向构造函数的prototypeprototype原型对象相当于特定类型所有实例对象都可以访问的公共容器。
来看看代码:

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
image.png

然后我们接着在p.__proto__.__protp__中寻找,我们发现找到了valueOf()函数。

查找valueOf大致流程:

  1. 在实例对象arr中查找valueOf属性,找到返回。
  2. 没有找到,通过arr.__proto__,找到arr构造函数的prototype并且查找上面的属性和方法,找到后返回。
  3. 没有找到,把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

相关文章

网友评论

    本文标题:浅析原型和原型链

    本文链接:https://www.haomeiwen.com/subject/fkulnftx.html