JS的原型链相关(待续)

2016-07-13  本文已影响18人  郝翔

首先列出经常会听到的属性,之后来说明它们之间的关系,再进一步解释如何通过这些属性构建JS的层层继承。

属性

proto所有的对象都拥有这个属性,这个属性是继承的关键。
prototype是函数独有的一个属性,在使用new来构建新对象时,它与新对象的proto属性有关。
__proto属性与prototype属性都是对象。

这些属性本身没有什么特别,但它们之间的关系却比较复杂,下面加上代码的印证,说清楚他们之间的关系。

基础实现

这里新建一个函数,函数也是对象,它有自己的属性,我们为它的prototype(原型链)属性添加一个方法introduce,之后通过new方法新建一个子类,输出子类car的name属性,调用子类的方法

function Car (name) {
    this.name = name;
}
Car.prototype.introduce = function () {
    console.log('Hello, my name is: ' + this.name);
}
var car = new Car('Alice');
console.log(car.name);
car.introduce();

继承的实现

我们学习面向对象的编程语言,很多时候是为了提高效率和正确性,而继承是实现这两点的关键,既然需要实现继承,那么来JS中是如何实现的。

JS创造了prototype属性在通过函数构造子类时生成proto属性,通过proto_属性来连接子类和父类。

于是,我们先从prototype属性说起,先明确一点,这个属性是函数特有的,这个属性的作用是为了在使用new来构造新对象实例时,可以让对象实例共享一些函数。

对于上面的代码,在使用Car这个构造函数构建的对象实例后,所有的新构建的对象实例都会拥有方法introduce。
理解了这里,我们来整体看一次。
先定义一个构造函数Car,之后为其原型添加方法,接着使用new标识符通过构造函数来新建一个对象。等等,这里需要听一下,为什么一个new可以有这么大的作用,这里面发生了什么?

new

那我们先说说new,它的确执行了好几个步骤,才产生了一个新对象。

  1. 首先新建一个空对象car,每个对象在创建之后,就会拥有一个proto隐藏属性,这个属性会原本指向Object属性的原型对象,可以通过下面的代码一窥究竟
var a = {}
a.__proto__
Object {}
    __defineGetter__:__defineGetter__()
    constructor:Object()
    ...
a.__proto__ === Object.prototype
// true
  1. 改变proto属性的指向,将它指向Car函数的prototype属性
  2. 让Car函数内部的this指向新建的对象car
  3. 执行构造函数,构造函数也是函数,但这个构造函数并没有返回任何值,但在它执行的过程中,由于this是指向新对象car的,所以它会为car的name属性赋值。执行完毕后,car对象会拥有name属性。

原型链上的方法

由于现在car.proto引用了Car.prototype引用的对象,那么他们会共享属性。

上一篇下一篇

猜你喜欢

热点阅读