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.
网友评论