简体   繁体   English

如何使用OLOO模式在JavaScript中实现继承

[英]How to achieve inheritance in javascript using OLOO pattern

I am trying to achieve inheritance of this code snippet 我正在尝试实现此代码段的继承

 function parent(name) { this.name = name; } function child(childname) { parent.call(this, "cde"); this.childname = childname; } var p1 = new parent("abc"); child.prototype = Object.create(parent.prototype); var p2 = new child("def"); console.log(p1.name); console.log(p2.name); 

Using OLOO pattern OLOO pattern 使用OLOO模式OLOO模式

Here is my try for it 这是我的尝试

 function person(name) { this.name = name; } var p1 = new person("abc"); var p2; p2 = Object.create(person); console.log(p2.name); p2.childname = "def"; 

While creating p2 object here im not sending name to it. 在这里创建p2对象时,我不会向其发送名称。 How can send name to it while creating p2 object . 创建p2对象时如何向其发送名称。

Can some one please explain is this the right approach to achieve inheritance using OLOO pattern 可以请一个解释一下这是使用OLOO模式实现继承的正确方法

Thanks 谢谢

Both the current answers posted here are "correct" in that they appropriately apply object-only prototype linkage (without constructors). 这里发布的两个当前答案都是“正确的”,因为它们适当地应用了仅对象原型链接(没有构造函数)。 I would make two points of clarification, though: 不过,我要澄清两点:

  1. I would never recommend "shadowing" of properties (or methods, for that matter), meaning having both p1 and p2 objects having a .name property on them. 我绝不建议对属性(或方法)进行“阴影处理”,这意味着在p1p2对象上都具有.name属性。 This is one of the most common sources of confusion, IME, with JS prototypes. 这是最常见的混淆源之一,IME与JS原型。 I always recommend using different property names on each object in a prototype chain. 我总是建议在原型链中的每个对象上使用不同的属性名称。

  2. OLOO is not just about wiring up a traditional "inheritance" hierarchy without using constructors, as the OP appears to be doing. OLOO不仅仅是在不使用构造函数的情况下连接传统的“继承”层次结构,就像OP似乎正在做的那样。 That's valid, but a very reduced, simplified view of OLOO. 这是有效的,但是简化了OLOO的视图。 OLOO is really intended to build off that capability to model software differently than with "classes". OLOO的真正目的是建立这种功能,以不同于“类”的方式对软件进行建模。 The point of OLOO is so that you set up two peer objects where one can delegate to the other (and vice versa, if you like) so they can virtually compose during the call-time of a method; OLOO的要点是,您可以设置两个对等对象,其中一个可以委托给另一个对等对象(如果愿意,反之亦然),以便它们可以在方法的调用期间虚拟地组成。 aka: Behavior Delegation. aka:行为委派。 Consult Chapter 6 of my "YDKJS: this & Object Prototypes" book for more info. 有关更多信息,请查阅我的“ YDKJS:此和对象原型”一书的第6章

There are some misconceptions both in the question and answer, so I feel the need to clarify first a few things: 在问答中都存在一些误解,因此我认为有必要先澄清一些事情:

  • There is no inheritance in the patterns you are referring to in js : in the OLOO pattern but also in the "fake" Class object pattern. 您在js中引用的模式没有继承 :在OLOO模式中,在“ fake” Class对象模式中也没有。 The reason is inheritance implies copying (you make new copies from the class everytime you call the constructor) and in both patterns or whenever you use new or Object.create() it's all about linking . 原因是继承意味着复制(您每次调用构造函数时都从类中创建新副本),并且在两种模式下或者每当您使用newObject.create()它都与链接有关。 In your case, what you are trying to do is to link two objects so that one works as a "fallback" for the other (through the [[prototype]] mecanism). 在您的情况下,您想要做的是链接两个对象,以便一个对象充当另一个对象的“后备”(通过[[prototype]]机制)。 And I repeat, this is NOT inheritance. 我再说一遍,这不是继承。
  • Also, there are no "constructors" in js, only "constructor calls" (which are made using a function + new)... From chapter 4 of this & Object prototypes book of Kyle Simpson's You Don't Know JS series : 此外,js中没有“构造函数”,只有“构造函数调用”(使用函数+新建)...从Kyle Simpson的“ 您不知道JS系列” 和对象原型书的第4章中:

In the above snippet, it's tempting to think that Foo is a "constructor", because we call it with new and we observe that it "constructs" an object. 在上面的代码片段中,很容易想到Foo是“构造函数”,因为我们用new来调用它,并且观察到它“构造”了一个对象。

In reality, Foo is no more a "constructor" than any other function in your program. 实际上,Foo不再是程序中的任何其他函数的“构造函数”。 Functions themselves are not constructors. 函数本身不是构造函数。 However, when you put the new keyword in front of a normal function call, that makes that function call a "constructor call". 但是,当将new关键字放在常规函数调用的前面时,这会使该函数调用成为“构造函数调用”。 In fact, new sort of hijacks any normal function and calls it in a fashion that constructs an object, in addition to whatever else it was going to do. 实际上,除了将要执行的任何其他操作之外,新的劫持形式还会劫持任何常规函数并以构造对象的方式对其进行调用。

  • Also it is not necessary to use Object.prototype in the OLOO pattern as any object is normally "falling back" on it as you can see on the copy of page 127 of Kyle Simpson's YDKJS book. 同样,也不必在OLOO模式中使用Object.prototype,因为任何对象通常都在其中“回退”,正如您在Kyle Simpson的YDKJS书的第127页的副本上所看到的。 在此处输入图片说明

Finally, here is my answer (though it is not easy to understand what you really want to achieve...): 最后,这是我的答案(尽管要真正理解要实现的目标并不容易...):

 // a "parent" object with an "init" function let Parent = { define: function (name) { this.name = name; } }; // a child object with another "init" function let Child = Object.create(Parent); // different name for init() : useful to differentiate with Parent Child.create = function (childname) { this.define("cde"); this.childname = childname; }; let p1 = Object.create(Parent); p1.define("abc"); let p2 = Object.create(Child); p2.create("def"); console.log(p1.name); console.log(p2.name); 

Using OLOO, you'd go for 使用OLOO,您将

var p1 = Object.create(Object.prototype);
p1.name = "abc";

var p2 = Object.create(p1);
p2.name = "cde";
p2.childname = "def";

or if you prefer 或者如果您愿意

var p1 = {
   name: "abc"
};

var p2 = Object.assign(Object.create(p1), {
    name: "cde",
    childname: "def"
});

Notice that OLOO does absolutely not use constructors. 请注意,OLOO绝对不使用构造函数。 If you want to avoid repetition, use factory function that simply return the above expressions and are parameterised to your liking. 如果要避免重复,请使用工厂函数,该函数仅返回上述表达式并根据您的喜好进行参数设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM