JavaScript的原型链到底是什么?

2017-04-18  本文已影响184人  陈学谦_

1.proto与prototype:

首先,proto 叫做内部原型,prototype 叫做构造器原型

prototype就像构造函数的工具箱一样,里面装着各种各样的工具,并且一直伴随着构造函数。如下图

而对象是没有这个属性的,因为对象就像一个成品,至于这个成品有什么功能都是由其模具(构造函数)决定的。所以prototype被称为“构造器原型”。

其次,我们所说的“找原型链”其实不是从prototype属性中找,而是从proto属性中找

比如说我们有一个构造函数Student,它实例化了一个对象 stu,我们需要用到stu的say()方法,那么它会去其proto属性内寻找有没有这个方法,而对象的proto属性指向其构造函数的prototype属性,也就是
stu.proto === Student.prototype,这样一来对象stu就会去Student.prototype中寻找是否有say()这个方法。

如果在上一层没找到say()方法,那么它会继续往Student.prototype的proto中寻找,也就是stu. proto . proto对象的proto属性指向其构造函数的prototype属性,并且Student.prototype是一个对象,它的构造函数是Object,因此它会去Object.prototype中寻找

prototype显得像个接收器...

因此真正的“找原型链”实际上是从proto里面找有没有想要的属性或方法,所以proto被称为“内部原型”。

proto并不是W3C标准,只是浏览器对原型的一种实现手段。
亲测支持proto属性的浏览器有:Chrome, FireFox, Opera, Edge, 没有Mac系统,Safari是否支持不知道,IE不支持。
因此除非用于调试,请不要在代码中出现proto,至于怎么间接借用proto利用原型链,我们将在下面讲到。

2. 如何借用proto利用原型链?

我们需要用到原型链无非就是想用到原型链上一层中的方法。上文说过,对象的proto属性指向其类的prototype属性(对象.proto === 类.prototype),我们就可以利用这一点把几个类在原型链中连接起来。

我们先声明一个Person类,之后在这个类的prototype属性上添加say方法。

var Person = function () {};
Person.prototype.say = function () {    
  console.log("Person say.");
};

之后我们再声明一个Student类

var Student = function () {};

这时如果我们若要使Student类能使用Person类的公共方法say就需要把Student类的prototype属性加到原型链中,将Student.prototype与Person.prototype串起来

如图

但是要通过什么方式连接呢?就是利用对象的proto属性指向其构造函数的prototype属性

如图

Student.prototype = new Person();

整体代码

var Person = function () {};
Person.prototype.say = function () {    
  console.log("Person say.");
};

var Student = function () {};

Student.prototype = new Person();

试验一下

var stu = new Student ();
stu.say(); // 输出 Person say.
上一篇 下一篇

猜你喜欢

热点阅读