更新时间:2018年10月26日16时37分 来源:传智播客 浏览次数:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | // 定义一个动物类functionAnimal (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 | functionCat(){ }Cat.prototype = newAnimal();Cat.prototype.name = 'cat';// Test Codevarcat = newCat();console.log(cat.name);console.log(cat.eat('fish'));console.log(cat.sleep());console.log(cat instanceofAnimal); //true console.log(cat instanceofCat); //true | 
| 01 02 03 04 05 06 07 08 09 10 11 | functionCat(name){  Animal.call(this);  this.name = name || 'Tom';}// Test Codevarcat = newCat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceofAnimal); // falseconsole.log(cat instanceofCat); // true | 
| 01 02 03 04 05 06 07 08 09 10 11 12 | functionCat(name){  varinstance = newAnimal();  instance.name = name || 'Tom';  returninstance;}// Test Codevarcat = newCat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceofAnimal); // trueconsole.log(cat instanceofCat); // false | 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 | functionCat(name){  varanimal = newAnimal();  for(varp inanimal){    Cat.prototype[p] = animal[p];  }  Cat.prototype.name = name || 'Tom';}// Test Codevarcat = newCat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceofAnimal); // falseconsole.log(cat instanceofCat); // true | 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | functionCat(name){  Animal.call(this);  this.name = name || 'Tom';}Cat.prototype = newAnimal();// 感谢 @学无止境c 的提醒,组合继承也是需要修复构造函数指向的。Cat.prototype.constructor = Cat;// Test Codevarcat = newCat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceofAnimal); // trueconsole.log(cat instanceofCat); // true | 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | functionCat(name){  Animal.call(this);  this.name = name || 'Tom';}(function(){  // 创建一个没有实例方法的类  varSuper = function(){};  Super.prototype = Animal.prototype;  //将实例作为子类的原型  Cat.prototype = newSuper();})();// Test Codevarcat = newCat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceofAnimal); // trueconsole.log(cat instanceofCat); //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 | functionAnimal (name) {  // 属性  this.name = name || 'Animal';  // 实例方法  this.sleep = function(){    console.log(this.name + '正在睡觉!');  }  //实例引用属性  this.features = [];}functionCat(name){}Cat.prototype = newAnimal();vartom = newCat('Tom');varkissy = newCat('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属性值已经变化了。 |