更新时间:2018年10月26日16时37分 来源:传智播客 浏览次数:
01 02 03 04 05 06 07 08 09 10 11 12 13 | // 定义一个动物类 function Animal (name) { // 属性 this .name = name || 'Animal' ; // 实例方法 this .sleep = function (){ console.log( this .name + '正在睡觉!' ); } } // 原型方法 Animal.prototype.eat = function (food) { console.log( this .name + '正在吃:' + food); }; |
01 02 03 04 05 06 07 08 09 10 11 12 | function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat' ; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.eat( 'fish' )); console.log(cat.sleep()); console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true |
01 02 03 04 05 06 07 08 09 10 11 | function Cat(name){ Animal.call( this ); this .name = name || 'Tom' ; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true |
01 02 03 04 05 06 07 08 09 10 11 12 | function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom' ; return instance; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | function Cat(name){ var animal = new Animal(); for ( var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom' ; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | function Cat(name){ Animal.call( this ); this .name = name || 'Tom' ; } Cat.prototype = new Animal(); // 感谢 @学无止境c 的提醒,组合继承也是需要修复构造函数指向的。 Cat.prototype.constructor = Cat; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | function Cat(name){ Animal.call( this ); this .name = name || 'Tom' ; } ( function (){ // 创建一个没有实例方法的类 var Super = function (){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super(); })(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true 感谢 @bluedrink 提醒,该实现没有修复constructor。 Cat.prototype.constructor = Cat; // 需要修复下构造函数 |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | function Animal (name) { // 属性 this .name = name || 'Animal' ; // 实例方法 this .sleep = function (){ console.log( this .name + '正在睡觉!' ); } //实例引用属性 this .features = []; } function Cat(name){ } Cat.prototype = new Animal(); var tom = new Cat( 'Tom' ); var kissy = new Cat( 'Kissy' ); console.log(tom.name); // "Animal" console.log(kissy.name); // "Animal" console.log(tom.features); // [] console.log(kissy.features); // [] tom.name = 'Tom-New Name' ; tom.features.push( 'eat' ); //针对父类实例值类型成员的更改,不影响 console.log(tom.name); // "Tom-New Name" console.log(kissy.name); // "Animal" //针对父类实例引用类型成员的更改,会通过影响其他子类实例 console.log(tom.features); // ['eat'] console.log(kissy.features); // ['eat'] 原因分析: 关键点:属性查找过程 执行tom.features.push,首先找tom对象的实例属性(找不到), 那么去原型对象中找,也就是Animal的实例。发现有,那么就直接在这个对象的 features属性中插入值。 在console.log(kissy.features); 的时候。同上,kissy实例上没有,那么去原型上找。 刚好原型上有,就直接返回,但是注意,这个原型对象中features属性值已经变化了。 |