原型继承应该算是js里的最难点之一,以前确实知道怎么实现,但隔了这么久回过头想想,发现有些概念变得模糊了,虽然在coffeescript里用extends一句话就能实现,但coffee最终还是编译成js,所以还是有必要重新整理一番,温故而知新
一、关键字new与构造函数
1 2
| var array = new Array(10) var today = new Date()
|
我们都知道用new关键字实例化一个对象,new后面必须跟一个函数调用,也就是构造函数(constructor),构造函数用来初始化实例的属性和方法
可是具体过程是怎么样的呢?实际上只有两步:
第一步,**new创建了一个新的没有任何属性的空对象,然后将构造函数作为这个空对象的方法调用,此时构造函数中的this**关键字指向的便是这个空对象,这样一来便设置了这个空对象的所有属性,完成属性初始化
第二步,创建完这个空对象后,new又干了一件事儿,设置对象的原型__proto__,这个__proto__指向的是构造函数的prototype属性的值
每个对象都有__proto__属性,每个函数都有prototype属性,而__proto__总是指向其构造函数的prototype属性。 当一个函数被创建的时候,其prototype被自动创建并初始化,此时prototype对象只有一个属性,那便是constructor,它指回到这个被创建的函数(这就是为什么每个对象有个constructor属性的原因),添加给prototype对象的任何属性都会成为被构造函数实例化的对象的属性或方法
1 2 3 4 5 6 7 8 9 10 11
| var Dog = function(){ this.name = "狗腿子" } Dog.prototype.sayHello = function(){ console.log("你好") } Dog.prototype.constructor === Dog var dog = new Dog() dog.constructor === dog.__proto__.constructor dog.__proto__.constructor === Dog dog.sayHello()
|