Closed sailei1 closed 4 years ago
在 JavaScript 中,[[Prototype]] 机制会把对象关联到其他对象。无论你多么努力地说服自己,JavaScript 中就是没有类似“类”的抽象机制。 委托最好在内部实现,不要直接暴露出去
两个或两个以上互相(双向)委托的对象之间创建循环委托。如果你把 B 关联到A 然后试着把 A 关联到 B,就会出错。 当你使用对象关联风格来编写代码并使用行为委托设计模式时,并不需要关注是谁“构造了”对象(就是使用 new 调用的那个函数)。 JavaScript 中 的 函 数 之 所 以 可 以 访 问 call(..)、apply(..) 和 bind(..),就是因为函数本身是对象。而函数对象同样有 [[Prototype]] 属性并且关联到 Function.prototype 对象,因此所有函数对象都可以通过委托调用这些默认方法。
“类”和“委托”这两种设计模式的理论区别
function Foo(who) { this.me = who; } Foo.prototype.identify = function() { return "I am " + this.me; }; function Bar(who) { Foo.call( this, who ); } Bar.prototype = Object.create( Foo.prototype ); Bar.prototype.speak = function() { alert( "Hello, " + this.identify() + "." ); }; var b1 = new Bar( "b1" ); var b2 = new Bar( "b2" ); b1.speak(); b2.speak();
Foo = { init: function(who) { this.me = who; }, identify: function() { return "I am " + this.me; } }; Bar = Object.create( Foo ); Bar.speak = function() { alert( "Hello, " + this.identify() + "." ); }; var b1 = Object.create( Bar ); b1.init( "b1" ); var b2 = Object.create( Bar ); b2.init( "b2" ); b1.speak(); b2.speak();
es6 class 尽管语法上得到了改进,但实际上这里并没有真正的类,class 仍然是通过 [[Prototype]]机制实现的。 es6 class 优点 1.不再引用杂乱的 .prototype 2.不再需要通过Object.create(..)来替换 .prototype 对象,也不需要设置 .proto 或者 Object.setPrototypeOf(..)。 3.可以通过super(..)来实现相对多态,这样任何方法都可以引用原型链上层的同名方法。
class C { constructor() { // 确保修改的是共享状态而不是在实例上创建一个屏蔽属性! C.prototype.count++; // this.count 可以通过委托实现我们想要的功能 console.log( "Hello: " + this.count ); } } // 直接向 prototype 对象上添加一个共享状态 C.prototype.count = 0; var c1 = new C(); // Hello: 1 var c2 = new C(); // Hello: 2 c1.count === 2; // true c1.count === c2.count; // true //它违背了 class 语法的本意,在实现中暴露(泄露!)了 .prototype。
在 JavaScript 中,[[Prototype]] 机制会把对象关联到其他对象。无论你多么努力地说服自己,JavaScript 中就是没有类似“类”的抽象机制。 委托最好在内部实现,不要直接暴露出去
两个或两个以上互相(双向)委托的对象之间创建循环委托。如果你把 B 关联到A 然后试着把 A 关联到 B,就会出错。 当你使用对象关联风格来编写代码并使用行为委托设计模式时,并不需要关注是谁“构造了”对象(就是使用 new 调用的那个函数)。 JavaScript 中 的 函 数 之 所 以 可 以 访 问 call(..)、apply(..) 和 bind(..),就是因为函数本身是对象。而函数对象同样有 [[Prototype]] 属性并且关联到 Function.prototype 对象,因此所有函数对象都可以通过委托调用这些默认方法。
“类”和“委托”这两种设计模式的理论区别
es6 class 尽管语法上得到了改进,但实际上这里并没有真正的类,class 仍然是通过 [[Prototype]]机制实现的。 es6 class 优点 1.不再引用杂乱的 .prototype 2.不再需要通过Object.create(..)来替换 .prototype 对象,也不需要设置 .proto 或者 Object.setPrototypeOf(..)。 3.可以通过super(..)来实现相对多态,这样任何方法都可以引用原型链上层的同名方法。