【问题标题】:Best method for Prototype object oriented programming in JavaScriptJavaScript 中 Prototype 面向对象编程的最佳方法
【发布时间】:2011-08-20 12:05:19
【问题描述】:

我比较喜欢原型的编程方式,并且一直在尝试用 javascript 来理解它。

我在 The Good Parts 中看到了这段代码:

function beget(o){
  function F(){
    F.prototype = o;
  };
  return new F();
};

我一点也不明白,哈哈。如果您所要做的就是将原型设置为过去的对象,那么您就不能这样做吗:

var parent = {
  num = 66;
};
var child = {
  prototype: parent
};

这似乎不起作用,因为 child.num 返回为未定义。您如何描述 javascript 原型编程以及您的方法是什么? 谢谢大家

【问题讨论】:

  • 我想我真的把我发现的对象和函数弄糊涂了。虽然我不确定为什么需要有所不同。无论哪种方式,如果没有区别,那就更酷更简单了。我需要时间来思考这个

标签: javascript inheritance constructor prototype createobject


【解决方案1】:

个人认为最惯用的方法如下:

function Parent() {
    this.value = 2;
}

function Child() {

}

Child.prototype = new Parent();

var c = new Child();
alert(c instanceof Child); // true
alert(c instanceof Parent); // true
alert(c.value); // 2

【讨论】:

  • 不要忘记增加prototype.constructor 属性以指向Child :)
  • 这似乎对我不起作用:/ 当我这样做时 c.value 是未定义的
  • @Isaiah - 我已经在所有主流浏览器中运行了代码,并且每次都给出了预期的结果。
  • 虽然看起来像类,有没有办法做到这一点而不必使用新的?有没有办法只做 Child.value ?
【解决方案2】:

您只能将prototype 添加到函数对象。当通过 new 调用时,它将使用它作为原型。

顺便说一句,您引用的函数是新版本 ECMAScript 的一部分,名称为 Object.create(带有额外的 propertiesObject 参数)。

让我这么说吧:{object} 是一个单身。然而,function() object 是一个 构造函数,也就是说,当使用 new 调用时,会创建一个 instance(通过执行函数的主体,然后使用构造函数的原型)。当然原型也可以是一个函数对象,有自己的原型等等。SpecializationGeneralization就是在原型链上走上走下。

【讨论】:

  • 所以...你只能从function=>function继承?这似乎很愚蠢
  • @Isaiah - 这不是一个好的思考方式。对象继承用于创建对象的函数的道具/方法。它实际上是一个非常强大的范式,一旦你明白了。
  • 但是为什么一个对象不能从另一个对象继承呢?似乎有限,我正在努力解决它我发誓哈哈
  • 函数 对象,不要仅仅将它们视为可以调用的独立实体 :) 你可能对 Crockford 的“函数 - 终极”演讲感兴趣 - @ 987654322@
  • 我希望我能理解这一点,但我现在无法理解。我会一直使用到我能理解为止。感谢您让我知道这现在存在于标准中。
【解决方案3】:

第二个示例不起作用,因为您只是设置了对象的属性。 您要做的是设置构造函数的原型属性,然后从该函数创建一个对象。

var parent = {
   num : 666
};

function ChildConstructor(){
   console.log(this.num);
}
ChildConstructor.prototype = parent;

var child = new ChildConstructor();

http://jsfiddle.net/W9C3K/

如果没有专有方法,就不可能在对象上设置或更改原型。

【讨论】:

  • 只是好奇,为什么要使用new?似乎增加了我的代码膨胀,有没有办法让 ChildConstructor.num 工作?
  • 简单的答案:如果没有新的,您无法创建 ChildConstructor 的多个对象(o:有点复杂的答案:这就是已经提到的 __proto__ 出现的地方。如果您创建一个新对象像这种情况发生:child.__proto__ = ChildConstructor.prototype; 如果您使用从原型“继承”的属性(如 .num),则解释器将使用此 __proto__ 属性。这确保从原型获取的属性“子”可用, 即使你在创建了一些对象之后给构造函数分配了一个新的原型。
【解决方案4】:

.prototype 属性对 JavaScript 有特殊意义,但仅适用于函数,这就是您的代码不起作用的原因。

使用“典型继承”,您不会从基类继承。相反,您从一些对象开始并创建一个新对象,使用第一个对象作为原型。然后向新创建的对象添加属性和方法。

我不确定您所说的“您的方法是什么?”是什么意思?你是指编程方法,还是类似的东西?

更新: 你的问题非常广泛,我认为我不能在这里用简短的回答来公正地回答。你可能想看看下面的 SO 问题,它对 JS 原型进行了很好的讨论,以及一些链接其他人认为对这个主题有帮助的东西。

How does JavaScript .prototype work?

【讨论】:

    【解决方案5】:
    var parent = {
      num : 66
    };
    var child = {
       __proto__: parent
    };
    

    【讨论】:

    • __proto__ 是非标准的,仅适用于某些浏览器/引擎。不过如果能正式曝光就好了。
    • 这太简单了,为什么没有这个标准?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 2015-04-28
    相关资源
    最近更新 更多