js难点精解-----原型和原型链的关系和应用

359 阅读3分钟

首先,要明确,在js中:

 1、每个函数对象都有一个 prototype属性,我们称之为原型属性

 2、每个对象都有一个 __proto__ 属性,(其实是指向他构造函数的原型)

 3、所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数

 4、函数对象和原型对象通过prototype和constructor属性进行相互关联.

在js中,“万物皆对象”,函数对象也是对象的一种。

对于新手来说,最难理解的就是prototype 和 proto 之间的关系。

先看区别:(盗个个人觉得还不错的图)

看如下demo:

functionPerson(){}

var will =newPerson()

它所对应的的原型图如下:

原型图解析:

1、 我们创建了一个 函数对象 叫做 Person,这个对象有 proto 和 prototype属性

2、 Person.prototype 是该函数的原型对象,该对象有 constructor 属性指向原函数对象,和__proto__指向 他原函数对象的 “父” 函数的原型对象,即Object.Protytype.

3、 我们知道js中所有的对象都是继承自 Object,就是图中 的 function Object,该对象为 最顶级函数对象,所有的对象的__proto__属性最终都指向了该对象的原型对象。即Object.prototype

4、 另外所有的函数对象都是继承自 Function的原型,Object也是一个函数对象,所以Object.protu === Function.prototype. 也是指向了 Function的原型

5、 对于Function 函数对象,他和所有其他函数对象一样有个__proto__指向了 Function.prototype, 而Function的原型中有constructor属性指向 Function对象。即 Function.proto === Function.prototype. Function === Function.Prototype.constructor

6、 同样在 顶级对象Object 的原型属性中也有 constructor属性指向 顶级对象本身。即 Object === Object.prototype.constructor.

7、 再看Persopn函数对象,Person有个一 __proto__指向 Function的原型,有个prototype属性指向了 他自己的原型。在Person的原型中,有 constructor属性指向 Person,有__proto__属性指向了Object的原型,即 Person === Person.prototype.constructor。 Person.proto === Function.prototype

8、 最后看一下通过Person创建的will对象。这个对象 有一个 __proto__属性指向它构造函数的原型。即will.proto === Person.prototype

(ps: 以上说的可能有点啰嗦,但是需要你每一句都精度完之后,就应该能理解对象的原型和原型链,以及js中的继承关系)

原型链的行程原理我们已经分析完了,下面看一下一个示例demo:

varA=function(){};

var a =newA();

console.log(a.__proto__); //A {}(即构造器function A 的原型对象)

console.log(a.__proto__.__proto__);//Object {}(即构造器function Object 的原型对象)

console.log(a.__proto__.__proto__.__proto__);//null

上述代码的继承关系如下图:

补充:

浏览器查找js对象中的属性的顺序:

A、查找本对象中可枚举的属性,有的话就返回,没有的话执行B

B、再去查找父 proto,从父元素继承的属性中可枚举的属性,有的话就返回,没有的话执行C

C、父对象的原型中也没有对象的属性的话,继续找找父元素的__proto__,查找父元素从父父元素(父元素的父元素)的可枚举属性,有的话就返回,没有的话继续按照继承原型链向上查找,直到顶级对象 Object

D、如果顶级对象Object中的可枚举属性中有该属性的话就返回,没有的话就返回undefined