我来自类对象语言,最近我一直在学习那些花哨的动态语言(JavaScript,Python和Lua),我想要一些关于如何在这些语言中使用OO的技巧.了解这种方法的缺陷和缺点以及与传统OO相比的优势将是有用的.
我得到的一般概念是基于原型的OO基本上是用对象编程但没有关于如何使用它们的标准,而在普通的OO中有一个固定的预定义方式来制作和使用对象.
总之,这种方法的好处,坏处和丑处是什么?
基于原型的OO很难用于静态类型检查,有些人可能认为这是一个坏的或丑陋的事情.基于Prototype的OO 确实有一种创建新对象的标准方法,您可以克隆和修改现有对象.你也可以建造工厂等.
我认为人们最喜欢的("好")是基于原型的OO非常轻巧和灵活,提供非常高的功率重量比.
有关如何使用基于原型的面向对象的提示,一个很好的起点是关于简洁力量的原创自我论文.
为了节省带宽,这是我在JavaScript中"如何模拟"类的答案的链接?(有或没有第三方库)".它包含进一步的参考和示例.
简短的回答:JavaScript的原型OO的核心是授权.在这种类型的OOP中,同一"类"的不同对象可以将方法和属性的处理委托给同一个原型(通常是第三个对象):
var foo = { property: 42, inc: function(){ ++this.counter; }, dec: function(){ --this.counter; } }; // Note: foo does not define `counter`.
让我们为foo作为原型的对象创建一个构造函数.实际上,未处理的所有内容都将被委托给foo.
var Bar = function(){ this.counter = 0; }; Bar.prototype = foo; // This is how we set up the delegation. // Some people refer to Bar (a constructor function) as "class". var bar = new Bar(); console.log(bar.counter); // 0 --- Comes from bar itself console.log(bar.property); // 42 --- Not defined in bar, comes from foo bar.inc(); // Not defined in bar => delegated to foo bar.inc(); bar.dec(); // Not defined in bar => delegated to foo // Note: foo.inc() and foo.dec() are called but this === bar // that is why bar is modified, not foo. console.log(bar.counter); // 1 --- Comes from bar itself
我们inc()
直接在栏上定义:
bar.inc = function(){ this.counter = 42; }; bar.inc(); // Defined in bar => calling it directly. // foo.inc() is not even called. console.log(bar.counter); // 42 --- Comes from bar
设置单继承链:
var Baz = function(){ this.counter = 99; }; Baz.protype = new Bar(); var baz = new Baz(); console.log(baz.counter); // 99 baz.inc(); console.log(baz.counter); // 100 console.log(baz instanceof Baz); // true console.log(baz instanceof Bar); // true console.log(baz instanceof Object); // true
干净,嗯?