Javascript Kyle Simpson 的 OLOO 模式与原型设计模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29788181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Kyle Simpson's OLOO Pattern vs Prototype Design Pattern
提问by shmuli
Does Kyle Simpson's "OLOO (Objects Linking to Other Objects) Pattern" differ in any way from the the Prototype design pattern? Other than coining it by something that specifically indicates "linking" (the behavior of prototypes) and clarifying that there's no to "copying" happening here (a behavior of classes), what exactly does his pattern introduce?
Kyle Simpson 的“OLOO(对象链接到其他对象)模式”与原型设计模式有什么不同吗?除了通过专门指示“链接”(原型的行为)的东西来创造它并澄清这里没有“复制”发生(类的行为)之外,他的模式究竟引入了什么?
Here's an example of Kyle's patternfrom his book, "You Don't Know JS: this & Object Prototypes":
下面是 Kyle在他的书“你不知道的 JS:this 和 Object Prototypes”中的模式示例:
var Foo = {
init: function(who) {
this.me = who;
},
identify: function() {
return "I am " + this.me;
}
};
var 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(); // alerts: "Hello, I am b1."
b2.speak(); // alerts: "Hello, I am b2."
回答by Kyle Simpson
what exactly does his pattern introduce?
他的模式究竟介绍了什么?
OLOO embraces the prototype chain as-is, without needing to layer on other (IMO confusing) semantics to get the linkage.
OLOO 按原样包含原型链,无需叠加其他(IMO 混淆)语义来获得链接。
So, these two snippets have the EXACT same outcome, but get there differently.
因此,这两个片段具有完全相同的结果,但到达那里的方式不同。
Constructor Form:
构造器形式:
function Foo() {}
Foo.prototype.y = 11;
function Bar() {}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.z = 31;
var x = new Bar();
x.y + x.z; // 42
OLOO Form:
OLOO表格:
var FooObj = { y: 11 };
var BarObj = Object.create(FooObj);
BarObj.z = 31;
var x = Object.create(BarObj);
x.y + x.z; // 42
In both snippets, an xobject is [[Prototype]]-linked to an object (Bar.prototypeor BarObj), which in turn is linked to third object (Foo.prototypeor FooObj).
在这两个片段中,一个x对象都链接[[Prototype]]到一个对象(Bar.prototype或BarObj),而后者又链接到第三个对象(Foo.prototype或FooObj)。
The relationships and delegation are identical between the snippets. The memory usage is identical between the snippets. The ability to create many "children" (aka, many objects like x1through x1000, etc) is identical between the snippets. The performance of the delegation (x.yand x.z) is identical between the snippets. The object creation performance isslower with OLOO, but sanity checking thatreveals that the slower performance is really not an issue.
片段之间的关系和委托是相同的。代码段之间的内存使用是相同的。创建许多“子项”(又名,许多对象,如x1throughx1000等)的能力在片段之间是相同的。片段之间的委托 (x.y和x.z)的性能是相同的。创建对象的性能是与0100比较慢,但理智检查表明,较慢的性能真的不是一个问题。
What I argue OLOO offers is that it's much simpler to just express the objects and directly link them, than to indirectly link them through the constructor/newmechanisms. The latter pretends to be about classes but really is just a terrible syntax for expressing delegation (side note:so is ES6 classsyntax!).
我认为 OLOO 提供的是,仅表达对象并直接链接它们比通过构造函数/new机制间接链接它们要简单得多。后者假装是关于类,但实际上只是表达委托的一种糟糕的语法(旁注:ES6class语法也是如此!)。
OLOO is just cutting out the middle-man.
OLOO 只是切断了中间人。
Here's another comparisonof classvs OLOO.
这是与 OLOO的另一个比较class。
回答by Ed Hinchliffe
I read Kyle's book, and I found it really informative, particularly the detail about how thisis bound.
我读了凯尔的书,我发现它真的很有用,特别是关于如何this装订的细节。
Pros:
优点:
For me, there a couple of big pros of OLOO:
对我来说,OLOO 有几个优点:
1. Simplicity
1. 简单
OLOO relies on Object.create()to create a new object which is [[prototype]]-linked to another object. You don't have to understand that functions have a prototypeproperty or worry about any of the potential related pitfalls that come from its modification.
OLOO 依赖于Object.create()创建一个链接[[prototype]]到另一个对象的新对象。您不必了解函数具有prototype属性,也不必担心任何来自其修改的潜在相关陷阱。
2. Cleaner syntax
2. 更简洁的语法
This is arguable, but I feel the OLOO syntax is (in many cases) neater and more concise than the 'standard' javascript approach, particularly when it comes to polymorphism (super-style calls).
这是有争议的,但我觉得 OLOO 语法(在许多情况下)比“标准”javascript 方法更简洁、更简洁,尤其是在涉及多态性(super-style 调用)时。
Cons:
缺点:
I think there is one questionable bit of design (one that actually contributes to point 2 above), and that is to do with shadowing:
我认为有一个有问题的设计(一个实际上有助于上述第 2 点),这与阴影有关:
In behaviour delegation, we avoid if at all possible naming things the same at different levels of the
[[Prototype]]chain.
在行为委托中,我们尽可能避免在
[[Prototype]]链的不同级别命名相同的事物。
The idea behind this is that objects have their own more specific functions which then internally delegate to functions lower down the chain. For example, you might have a resourceobject with a save()function on it which sends a JSON version of the object to the server, but you may also have a clientResourceobject which has a stripAndSave()function, which first removes properties that shouldn't be sent to the server.
这背后的想法是,对象有自己更具体的功能,然后在内部委托给链下层的功能。例如,您可能有一个resource带有save()函数的对象,该函数将对象的 JSON 版本发送到服务器,但您也可能有一个clientResource具有stripAndSave()函数的对象,该函数首先删除不应发送到服务器的属性.
The potential problem is: if someone else comes along and decides to make a specialResourceobject, not fully aware of the whole prototype chain, they might reasonably* decide to save a timestamp for the last save under a property called save, which shadows the base save()functionality on the resourceobject two links down the prototype chain:
潜在的问题是:如果其他人出现并决定创建一个specialResource对象,而不完全了解整个原型链,他们可能会合理*决定在名为 的属性下保存最后一次保存的时间戳,该属性save将基本save()功能隐藏在该resource物体的两个环节下来的原型链:
var resource = {
save: function () {
console.log('Saving');
}
};
var clientResource = Object.create(resource);
clientResource.stripAndSave = function () {
// Do something else, then delegate
console.log('Stripping unwanted properties');
this.save();
};
var specialResource = Object.create( clientResource );
specialResource.timeStampedSave = function () {
// Set the timestamp of the last save
this.save = Date.now();
this.stripAndSave();
};
a = Object.create(clientResource);
b = Object.create(specialResource);
a.stripAndSave(); // "Stripping unwanted properties" & "Saving".
b.timeStampedSave(); // Error!
This is a particularly contrived example, but the point is that specifically notshadowing other properties can lead to some awkward situations and heavy use of a thesaurus!
这是一个特别人为的例子,但重点是特别不屏蔽其他属性可能会导致一些尴尬的情况和大量使用同义词!
Perhaps a better illustration of this would be an initmethod - particularly poignant as OOLO sidesteps constructor type functions. Since every related object will likely need such a function, it may be a tedious exercise to name them appropriately, and the uniqueness may make it difficult to remember which to use.
也许一个更好的说明是一种init方法 - 特别是 OOLO 回避构造函数类型的方法。由于每个相关对象都可能需要这样的函数,因此适当地命名它们可能是一项乏味的练习,而且唯一性可能会让人难以记住使用哪个。
*Actually it's not particularly reasonable (lastSavedwould be much better, but it's just an example.)
*其实也不是特别合理(lastSaved会好很多,但这只是一个例子。)
回答by Marcus Junius Brutus
The discussion in "You Don't Know JS: this & Object Prototypes" and the presentation of the OLOO is thought-provoking and I have learned a ton going through the book. The merits of the OLOO pattern are well-described in the other answers; however, I have the following pet complaints with it (or am missing something that prevents me from applying it effectively):
“你不知道 JS:这个和对象原型”中的讨论和 OLOO 的介绍发人深省,我通过这本书学到了很多东西。其他答案中很好地描述了 OLOO 模式的优点;但是,我对它有以下宠物投诉(或者我遗漏了一些阻止我有效应用它的东西):
1
1
When a "class" "inherits" another "class" in the classical pattern, the two function can be declared similar syntax ("function declaration" or "function statement"):
当一个“类”“继承”经典模式中的另一个“类”时,这两个函数可以声明类似的语法(“函数声明”或“函数语句”):
function Point(x,y) {
this.x = x;
this.y = y;
};
function Point3D(x,y,z) {
Point.call(this, x,y);
this.z = z;
};
Point3D.prototype = Object.create(Point.prototype);
In contrast, in the OLOO pattern, different syntactical forms used to define the base and the derived objects:
相比之下,在 OLOO 模式中,用于定义基础对象和派生对象的不同句法形式:
var Point = {
init : function(x,y) {
this.x = x;
this.y = y;
}
};
var Point3D = Object.create(Point);
Point3D.init = function(x,y,z) {
Point.init.call(this, x, y);
this.z = z;
};
As you can see in the example above the base object can be defined using object literal notation, whereas the same notation can't be used for the derived object. This asymmetry bugs me.
正如您在上面的示例中看到的,可以使用对象文字表示法定义基础对象,而派生对象不能使用相同的表示法。这种不对称让我很烦恼。
2
2
In the OLOO pattern, creating an object is two steps:
在 OLOO 模式中,创建对象分两步:
- call
Object.create call some custom, non standard method to initialize the object (which you have to remember since it may vary from one object to the next):
var p2a = Object.create(Point); p2a.init(1,1);
- 称呼
Object.create 调用一些自定义的非标准方法来初始化对象(您必须记住,因为它可能因一个对象而异):
var p2a = Object.create(Point); p2a.init(1,1);
In contrast, in the Prototype pattern you use the standard operator new:
相反,在原型模式中,您使用标准运算符new:
var p2a = new Point(1,1);
3
3
In the classical pattern I can create "static" utility functions that don't apply directly to an "instant" by assigning them directly to the "class" function (as opposed to its .prototype). E.g. like function squarein the below code:
在经典模式中,我可以通过将它们直接分配给“类”函数(而不是它的.prototype)来创建不直接应用于“即时”的“静态”实用程序函数。例如像square下面代码中的函数:
Point.square = function(x) {return x*x;};
Point.prototype.length = function() {
return Math.sqrt(Point.square(this.x)+Point.square(this.y));
};
In contrast, in the OLOO pattern any "static" functions are available (via the [[prototype]] chain) on the object instances too:
相比之下,在 OLOO 模式中,对象实例上的任何“静态”函数都可用(通过 [[prototype]] 链):
var Point = {
init : function(x,y) {
this.x = x;
this.y = y;
},
square: function(x) {return x*x;},
length: function() {return Math.sqrt(Point.square(this.x)+Point.square(this.y));}
};
回答by Abhishek Sachan
"I figured to do it makes each obj dependent on the other"
“我想这样做会使每个 obj 依赖于另一个”
As Kyle explains when two objects are [[Prototype]]linked, they aren't really
dependent on each other; instead they are individual object. You're linking one
object to the other with a [[Prototype]]linkage which you can change anytime you wish. If you take two [[Prototype]]linked objects created through OLOO style as being dependent on each other, you should also think the same about the ones created through constructorcalls.
正如凯尔所解释的,当两个对象被[[Prototype]]链接时,它们并不是真正相互依赖;相反,它们是单独的对象。您通过一个链接将一个对象链接到另一个对象[[Prototype]],您可以随时更改该链接。如果将[[Prototype]]通过 OLOO 样式创建的两个链接对象视为相互依赖,那么您也应该考虑通过constructor调用创建的对象。
var foo= {},
bar= Object.create(foo),
baz= Object.create(bar);
console.log(Object.getPrototypeOf(foo)) //Object.prototype
console.log(Object.getPrototypeOf(bar)) //foo
console.log(Object.getPrototypeOf(baz)) //bar
Now think for a second do you think of foobarand bazas being dependent on each-other?
现在想了第二个你觉得foobar和baz为依赖于每个-其他?
Now let's do the same this constructorstyle code-
现在让我们做同样的constructor风格代码——
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype= Object.create(Foo);
Baz.prototype= Object.create(Bar);
var foo= new Foo(),
bar= new Bar().
baz= new Baz();
console.log(Object.getPrototypeOf(foo)) //Foo.prototype
console.log(Object.getPrototypeOf(Foo.prototype)) //Object.prototype
console.log(Object.getPrototypeOf(bar)) //Bar.prototype
console.log(Object.getPrototypeOf(Bar.prototype)) //Foo.prototype
console.log(Object.getPrototypeOf(baz)) //Baz.prototype
console.log(Object.getPrototypeOf(Baz.prototype)) //Bar.prototype
The only difference b/w the latter and the former code is that in the latter one
foo, bar, bazbbjects are linked to each-other through arbitrary objects
of their constructorfunction (Foo.prototype, Bar.prototype, Baz.prototype) but in the former one (OLOOstyle) they are linked directly. Both ways you're just linking foo, bar, bazwith each other, directly in the former one and indirectly in the latter one. But, in both the cases the objects are independent of each-other because it isn't really like an instance of any class which once instantiated, can't be made to inherit from some other class. You can always change which object an object should delegate too.
b/w 后者和前者代码的唯一区别在于,在后一个
foo, 中bar,baz对象通过其constructor函数 ( Foo.prototype, Bar.prototype, Baz.prototype) 的任意对象相互链接,而在前一个 (OLOO样式) 中,它们是直接链接的。这两种方法你只是链接foo,bar,baz相互直接在前一个和间接后者。但是,在这两种情况下,对象都是相互独立的,因为它不像任何类的实例,一旦实例化,就不能从其他类继承。您也可以随时更改对象应该委托的对象。
var anotherObj= {};
Object.setPrototypeOf(foo, anotherObj);
So they're all independent of each-other.
所以他们都是相互独立的。
" I was hoping
OLOOwould solve the issue in which each object knows nothing about the other."
“我希望
OLOO能解决每个物体对另一个物体一无所知的问题。”
Yes that's indeed possible-
是的,这确实有可能-
Let's use Techas an utility object-
让我们Tech用作实用程序对象-
var Tech= {
tag: "technology",
setName= function(name) {
this.name= name;
}
}
create as many objects as you wish linked to Tech-
创建您希望链接到的任意数量的对象Tech-
var html= Object.create(Tech),
css= Object.create(Tech),
js= Object.create(Tech);
Some checking (avoiding console.log)-
html.isPrototypeOf(css); //false
html.isPrototypeOf(js); //false
css.isPrototypeOf(html); //false
css.isPrototypeOf(js); //false
js.isPrototypeOf(html); //false
js.isPrototypwOf(css); //false
Tech.isPrototypeOf(html); //true
Tech.isPrototypeOf(css); //true
Tech.isPrototypeOf(js); //true
Do you think html, css, jsobjects are connected to each-other? No, they aren't. Now let's see how we could've done that with constructorfunction-
你认为html, css,js对象是相互连接的吗?不,他们不是。现在让我们看看我们如何用constructor函数来做到这一点——
function Tech() { }
Tech.prototype.tag= "technology";
Tech.prototype.setName= function(name) {
this.name= name;
}
create as many objects as you wish linked to Tech.proptotype-
创建您希望链接到的任意数量的对象Tech.proptotype-
var html= new Tech(),
css= new Tech(),
js= new Tech();
Some checking (avoiding console.log)-
一些检查(避免console.log)-
html.isPrototypeOf(css); //false
html.isPrototypeOf(js); //false
css.isPrototypeOf(html); //false
css.isPrototypeOf(js); //false
js.isPrototypeOf(html); //false
js.isPrototypeOf(css); //false
Tech.prototype.isPrototypeOf(html); //true
Tech.prototype.isPrototypeOf(css); //true
Tech.prototype.isPrototypeOf(js); //true
How do you think these constructor-style Objects (html, css, js)
Objects differ from the OLOO-style code? In fact they serve the same purpose. In OLOO-style one objects delegate to Tech(delegation was set explicitly) while in constructor-style one objects delegate to Tech.prototype(delegation was set implicitly). Ultimately you end up linking the three objects, having no linkage with each-other, to one object, directly using OLOO-style, indirectly using constructor-style.
你认为这些constructor-style Objects ( html, css, js) Objects 与OLOO-style 代码有何不同?事实上,它们的目的是相同的。在OLOO-style one 对象委托给Tech(委托被显式设置)而在constructor-style one 对象委托给Tech.prototype(委托被隐式设置)。最终,您最终将三个对象(彼此之间没有链接)链接到一个对象,直接使用OLOO-style,间接使用constructor-style。
"As is, ObjB has to be created from ObjA.. Object.create(ObjB) etc"
“按原样,ObjB 必须从 ObjA .. Object.create(ObjB) 等创建”
No, ObjBhere is not like an instance (in classical-based languages) of any class
ObjA. It sould be said like objBobject is made delegate to ObjAobject at it's creation
time". If you used constructor, you would have done the same 'coupling', although indirectly by making use of .prototypes.
不,ObjB这里不像任何类的实例(在基于经典的语言中)
ObjA。应该说对象在创建时objB被委托给ObjA对象”。如果您使用构造函数,您将完成相同的“耦合”,尽管是通过使用.prototypes间接完成的。
回答by Andrew Szymczak
@Marcus @bholben
@马库斯@bholben
Perhaps we can do something like this.
也许我们可以做这样的事情。
const Point = {
statics(m) { if (this !== Point) { throw Error(m); }},
create (x, y) {
this.statics();
var P = Object.create(Point);
P.init(x, y);
return P;
},
init(x=0, y=0) {
this.x = x;
this.y = y;
}
};
const Point3D = {
__proto__: Point,
statics(m) { if (this !== Point3D) { throw Error(m); }},
create (x, y, z) {
this.statics();
var P = Object.create(Point3D);
P.init(x, y, z);
return P;
},
init (x=0, y=0, z=0) {
super.init(x, y);
this.z = z;
}
};
Of course, creating a Point3D object that links to the prototype of a Point2D object is kind of silly, but that's beside the point (I wanted to be consistent with your example). Anyways, as far as the complaints go:
当然,创建一个链接到 Point2D 对象原型的 Point3D 对象有点愚蠢,但这不是重点(我想与您的示例保持一致)。无论如何,就投诉而言:
The asymmetry can be fixed with ES6's Object.setPrototypeOfor the more frowned upon
__proto__ = ...that I use. We can also use superon regular objects now too, as seen inPoint3D.init(). Another way would be to do something likeconst Point3D = Object.assign(Object.create(Point), { ... }though I don't particularly like the syntax.
不对称可以用 ES6 的Object.setPrototypeOf或
__proto__ = ...我使用的更不满意的方法来修复。我们现在也可以在常规对象上使用super,如Point3D.init(). 另一种方法是做类似的事情const Point3D = Object.assign(Object.create(Point), { ... }虽然我不是特别喜欢语法。
We can always just wrap
p = Object.create(Point)and thenp.init()into a constructor. e.g.Point.create(x,y). Using the code above we can create aPoint3D"instance" in the following manner.var b = Point3D.create(1,2,3); console.log(b); // { x:1, y:2, z:3 } console.log(Point.isPrototypeOf(b)); // true console.log(Point3D.isPrototypeOf(b)) // true
我们总是可以包装
p = Object.create(Point)然后p.init()进入构造函数。例如Point.create(x,y)。使用上面的代码,我们可以Point3D通过以下方式创建一个“实例”。var b = Point3D.create(1,2,3); console.log(b); // { x:1, y:2, z:3 } console.log(Point.isPrototypeOf(b)); // true console.log(Point3D.isPrototypeOf(b)) // true
I just came up with this hack to emulate static methods in OLOO. I'm not sure if I like it or not. It requires calling a special property at the top of any "static" methods. For example, I've made the
Point.create()method static.var p = Point.create(1,2); var q = p.create(4,1); // Error!
我刚刚想出了这个 hack 来模拟 OLOO 中的静态方法。我不确定我是否喜欢它。它需要在任何“静态”方法的顶部调用一个特殊的属性。例如,我将
Point.create()方法设为静态。var p = Point.create(1,2); var q = p.create(4,1); // Error!
Alternatively, with ES6 Symbolsyou can safely extend Javascript base classes. So you could save yourself some code and define the special property on Object.prototype. For example,
或者,使用 ES6 Symbols,您可以安全地扩展 Javascript 基类。因此,您可以为自己节省一些代码并在 Object.prototype 上定义特殊属性。例如,
const extendedJS = {};
( function(extension) {
const statics = Symbol('static');
Object.defineProperty(Object.prototype, statics, {
writable: true,
enumerable: false,
configurable: true,
value(obj, message) {
if (this !== obj)
throw Error(message);
}
});
Object.assign(extension, {statics});
})(extendedJS);
const Point = {
create (x, y) {
this[extendedJS.statics](Point);
...
回答by NenadPavlov
@james emanon - So, you are referring to multiple inheritance (discussed on page 75 in the book "You Don't Know JS: this & Object Prototypes"). And that mechanism we can find in underscore's "extend" function for example. Names of object you stated in your example are a bit mixing apples, oranges and candies but I understand the point behind. From my experience this would be OOLO version:
@james emanon - 所以,你指的是多重继承(在“你不知道 JS:这个和对象原型”一书中的第 75 页上讨论过)。例如,我们可以在下划线的“扩展”函数中找到这种机制。您在示例中提到的对象名称有点混合了苹果、橙子和糖果,但我理解背后的意思。根据我的经验,这将是 OOLO 版本:
var ObjA = {
setA: function(a) {
this.a = a;
},
outputA: function() {
console.log("Invoking outputA - A: ", this.a);
}
};
// 'ObjB' links/delegates to 'ObjA'
var ObjB = Object.create( ObjA );
ObjB.setB = function(b) {
this.b = b;
}
ObjB.setA_B = function(a, b) {
this.setA( a ); // This is obvious. 'setA' is not found in 'ObjB' so by prototype chain it's found in 'ObjA'
this.setB( b );
console.log("Invoking setA_B - A: ", this.a, " B: ", this.b);
};
// 'ObjC' links/delegates to 'ObjB'
var ObjC = Object.create( ObjB );
ObjC.setC = function(c) {
this.c = c;
};
ObjC.setA_C = function(a, c) {
this.setA( a ); // Invoking 'setA' that is clearly not in ObjC shows that prototype chaining goes through ObjB all the way to the ObjA
this.setC( c );
console.log("Invoking setA_C - A: ", this.a, " C: ", this.c);
};
ObjC.setA_B_C = function(a, b, c){
this.setA( a ); // Invoking 'setA' that is clearly not in ObjC nor ObjB shows that prototype chaining got all the way to the ObjA
this.setB( b );
this.setC( c );
console.log("Invoking setA_B_C - A: ", this.a, " B: ", this.b, " C: ", this.c);
};
ObjA.setA("A1");
ObjA.outputA(); // Invoking outputA - A: A1
ObjB.setA_B("A2", "B1"); // Invoking setA_B - A: A2 B: B1
ObjC.setA_C("A3", "C1"); // Invoking setA_C - A: A3 C: C1
ObjC.setA_B_C("A4", "B2", "C1"); // Invoking setA_B_C - A: A4 B: B2 C: C1
It is simple example but the point shown is that we are just chaining object together in rather flat structure/formation and still have possibility to use methods and properties from multiple object. We achieve same things as with class/"copying the properties" approach. Summed by Kyle (page 114, "this & Object Prototypes"):
这是一个简单的例子,但显示的要点是我们只是将对象以相当扁平的结构/形式链接在一起,并且仍然有可能使用来自多个对象的方法和属性。我们实现了与类/“复制属性”方法相同的东西。Kyle 总结(第 114 页,“this & Object Prototypes”):
In other words, the actual mechanism, the essence of what's important to the functionality we can leverage in JavaScript, is all about objects being linked to other objects.
换句话说,实际的机制,对于我们可以在 JavaScript 中利用的功能很重要的本质,都是关于将对象链接到其他对象。
I understand that more natural way for you would be to state all the "parent" (careful :) ) objects in one place/function call rather modeling whole chain.
我知道对您来说更自然的方法是在一个地方/函数调用中声明所有“父”(小心:))对象,而不是对整个链进行建模。
What it requires is shift in thinking and modeling problems in our applications according to that. I'm also getting used to it. Hope it helps and final verdict from the Kyle himself would be great. :)
它需要的是根据这一点在我们的应用程序中转变思维和建模问题。我也习惯了。希望它有所帮助,凯尔本人的最终判决会很棒。:)
回答by bholben
@Marcus, just like you, I have been keen on OLOO and also dislike the asymmetry as described in your first point. I've been playing with an abstraction to bring the symmetry back. You could create a link()function that is used in place of Object.create(). When used, your code could look something like this...
@Marcus,就像你一样,我一直热衷于 OLOO,也不喜欢你第一点中描述的不对称。我一直在玩抽象来恢复对称性。您可以创建一个link()函数来代替Object.create(). 使用时,您的代码可能如下所示...
var Point = {
init : function(x,y) {
this.x = x;
this.y = y;
}
};
var Point3D = link(Point, {
init: function(x,y,z) {
Point.init.call(this, x, y);
this.z = z;
}
});
Remember that Object.create()has a second parameter that can be passed in. Here is the link function that leverages the second parameter. It also allows a little bit of custom configuration...
请记住,它Object.create()具有可以传入的第二个参数。这是利用第二个参数的链接函数。它还允许一些自定义配置......
function link(delegate, props, propsConfig) {
props = props || {};
propsConfig = propsConfig || {};
var obj = {};
Object.keys(props).forEach(function (key) {
obj[key] = {
value: props[key],
enumerable: propsConfig.isEnumerable || true,
writable: propsConfig.isWritable || true,
configurable: propsConfig.isConfigurable || true
};
});
return Object.create(delegate, obj);
}
Of course, I think @Kyle would not endorse shadowing the init()function in the Point3D object. ;-)
当然,我认为@Kyle 不会支持init()在 Point3D 对象中隐藏函数。;-)
回答by james emanon
Is there a way to OLOO more than "two" objects.. all the examples I consist of the based example (see OP's example). Lets say we had the following objects, how can we create a "fourth" object that has the attributes of the 'other' three? ala...
有没有办法 OLOO 超过“两个”对象..我由基于示例组成的所有示例(参见 OP 的示例)。假设我们有以下对象,我们如何创建具有“其他”三个属性的“第四个”对象?翼...
var Button = {
init: function(name, cost) {
this.buttonName = name;
this.buttonCost = cost;
}
}
var Shoe = {
speed: 100
}
var Bike = {
range: '4 miles'
}
these objects are arbitrary, and could encompass all sorts of behaviors. But the gist is, we have 'n' number of objects, and our new object needs something from all three.
这些对象是任意的,可以包含各种行为。但要点是,我们有“n”个对象,而我们的新对象需要这三个对象中的一些东西。
instead of the given examples ala:
而不是给定的例子ala:
var newObj = Object.create(oneSingularObject);
newObj.whatever..
BUT, our newObject = (Button, Bike, Shoe)......
但是,我们的 newObject = (Button, Bike, Shoe)......
What is the pattern to get this going in OLOO?
在 OLOO 中实现这一目标的模式是什么?

