随后给创建好的Staff对象添加__proto__属性,并赋值为Function的构造器的prototype,这一步是所有对象创建过程中都有的步骤,在执行类似var x = new X()方式是,都会把X的prototype赋值给x的__proto__,类似如下的赋值: 复制代码 代码如下: Staff.__proto__ = Function.prototype;
接下来给Staff创建prototype属性,这一步是创建function类型的对象具有的步骤,创建的过程如下伪代码: 复制代码 代码如下: var o = new Object(); o.constructor = Base; Staff.prototype = o;
如上的分析我们可知,当创建对象时,会创建一个私有属性__proto__,当创建function是会创建一个prototype属性。因为Staff是一个function类型的对象,所以会同时具有这两个属性。 这两个属性是构建原型链的关键属性。我们来分析执行代码 var staff1 = new Staff(“hunter”)时,原型是如何传递的。 根据如上分析,staff1.__proto__ = Staff.prototype,而Staff.prototype又是一个由Object创建的对象,即Staff.prototype.__proto__ = Object.prototype,所以staff1.__proto__ .__proto__ 指向的是Object.prototype,即staff1.__proto__ .__proto__ == Object.prototype,这就是原型链,当要读取某个对象的属性时,JS首先找对象本身是否有这个属性,如果没有就会顺着原型链一直寻找这个属性。 知道了原型链的原理,那么就很容易根据这个原理来构建Javascript中的对象继承。 由如上的分析,我们可知原型链的顶端都是Object.prototype,这就意味着在构建的继承关系中Object是所有对象的基类,可以运行如下的代码验证。 复制代码 代码如下: Object.prototype.location = "China"; function Staff(name) { // 基类 this.name = name; } Staff.prototype.say = function() { alert(this.name + " say hello"); } var ManStaff1 = new Staff("hunter"); var ManStaff2 = new Staff("dangjian"); alert(ManStaff1.location); alert(ManStaff2.location);
运行结果知道,Object是Staff的基类,那么要如何构建一个Staff的子类呢? 理解了上面函数的建立原理,我们很容易写出如下的代码: 复制代码 代码如下: function Staff(name) { // 基类 this.name = name; } Staff.prototype.say = function() { alert(this.name + " say hello"); } function ManStaff(name, age) { // 子类 Staff.call(this,name); this.age = age; } ManStaff.prototype = new Staff(); // 建立继承关系 var ManStaff1 = new ManStaff("hunter", 22); var ManStaff2 = new ManStaff("dangjian", 32); ManStaff1.say(); ManStaff2.say();