js面向对象和面向委托的设计

1 原型链关联的几种方式
  • Bar.prototype = Foo.prototype;
  • Bar.prototype = new Foo();
  • Bar.prototype = Object.create(Foo.prototype);
    第一种方式,仅复制的引用,Foo或Bar原型链上的修改会相互影响;
    第二种方式,调用了Foo的“构造函数”,可能会有东西影响到后代,会有副作用;
    第三种方式,Object.create(...),用指定的对象来替换新创建对象的__proto__
2 面向对象与面向委托的设计

2.1 先看面向对象的设计

function Animal (name) {
  this.name = name;
}
Animal.prototype.introduce = function() {
  return `I'm ${this.name}`;
}
function Cat (name) {
  Animal.call(this, name);
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.say = function () {
  console.log(this.introduce());
}
var maleHelloKitty = new Cat('male hellokitty');
maleHelloKitty.say(); // 'I'm male hellokitty'
var femaleHelloKitty = new Cat('female hellokitty');
femaleHelloKitty.say(); // 'I'm female hellokitty'

2.2 es6的面向对象设计,思想与2.1相同,仅仅是语法的改变

class Animal {
  constructor (name) {
    this.name = name;
  }
  introduce () {
    return `I'm ${this.name}`;
  }
}
class Cat extends Animal {
  constructor (name) {
    super(name);
  }
  say () {
    console.log(this.introduce());
  }
}
var maleHelloKitty = new Cat('male hellokitty');
maleHelloKitty.say(); // 'I'm male hellokitty'
var femaleHelloKitty = new Cat('female hellokitty');
femaleHelloKitty.say(); // 'I'm female hellokitty'

2.3 面向委托的设计

var Animal = {
  init: function (name) {
    this.name = name;
  },
  introduce: function () {
    return `I'm ${this.name}`;
  }
};
var Cat = Object.create(Animal);
Cat.say = function () {
  console.log(this.introduce());
}
var maleHelloKitty = Object.create(Cat);
maleHelloKitty.init('male hellokitty');
maleHelloKitty.say(); // 'I'm male hellokitty'
var femaleHelloKitty = Object.create(Cat);
femaleHelloKitty.init('female hellokitty');
femaleHelloKitty.say(); // 'I'm female hellokitty'

2.4 比较
面向对象的设计,现比较普遍。把对象抽象成,有继承、多态等特点;缺点有杂乱的.prototype引用、视图调用原型链上层同名函数的显式伪多态以及不可靠、不美观的.constructor;
面向委托的设计,认为对象之间是兄弟关系,互相委托,而不是父类与子类的关系。是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类;
按照实际需要,选用不同设计方式即可。

参考《你不知道的JavaScript》上卷 / Simpson, K.

你可能感兴趣的:(js面向对象和面向委托的设计)