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.
网友评论