[[Prototype]] 机制就是指对象中的一个内部链接引用 另一个对象。JavaScript 中这个机制的本质就是对象之间的关联关系
面向委托的设计模式
为了更好地学习如何更直观地使用 [[Prototype]],我们必须认识到它代表的是一种不同
于类(参见第 4 章)的设计模式。
类理论
类设计模式鼓励你在继承时使用方法重写(和多态)
委托理论
1 | Task = { |
将XYZ委托给Task, 当XYZ对象执行setID方式时,该对象本身并没有该方法,会沿着原型链查找到Task对象上,
this.id = ID其实是隐式绑定。当前的this绑定这XYZ并不是Task
打印XYZ与Task对象的属性,如下:
1 | { prepareTask: [Function], |
委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一
个对象(Task)。
这种设计模式需要注意的几个问题:
委托中最好把状态保存在委托者(XYZ、ABC)而不是委托目标(Task)上。如上例子中,id与label都属于对象XYZ
进行避免在不同级别中使用相同的方法或属性命名,提倡更有描述性的方法名,尤其是要写清相应对象行为的类型。
使用this的隐式绑定,将需要的属性绑定到委托者身上,尤其是对于一些私有的数据属性,这并不需要保存在委托目标上。
互相委托(禁止)
你无法在两个或两个以上互相(双向)委托的对象之间创建循环委托。如果你把 B 关联到 A 然后试着把 A 关联到 B,就会出错。
之所以要禁止互相委托,是因为引擎的开发者们发现在设置时检查(并禁止!)一次无限 循环引用要更加高效,否则每次从对象中查找属性时都需要进行检查。
比较思维模型
对比JavaScript中面向对象与对象关联两种设计模式:
1 | function Foo(who) { this.me = who; |
子类 Bar 继承了父类 Foo,然后生成了 b1 和 b2 两个实例。b1 委托了 Bar.prototype,后者
委托了 Foo.prototype。
1 | Foo = { |
对象关联风格代码的思维模型
对象之间的关联关系。
小结
行为委托认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。JavaScript 的 [[Prototype]] 机制本质上就是行为委托机制。也就是说,我们可以选择在 JavaScript 中努 力实现类机制(参见第 4 和第 5 章),也可以拥抱更自然的 [[Prototype]] 委托机制。
当你只用对象来设计代码时,不仅可以让语法更加简洁,而且可以让代码结构更加清晰。
对象关联(对象之前互相关联)是一种编码风格,它倡导的是直接创建和关联对象,不把
它们抽象成类。对象关联可以用基于 [[Prototype]] 的行为委托非常自然地实现。