【问题标题】:How to inherit correctly in javascript?如何在javascript中正确继承?
【发布时间】:2011-09-12 15:50:39
【问题描述】:

我的理解是,如果对象具有给定成员而不检查原型链,则“hasOwnProperty”返回true。但是当我从其他对象继承时,我会看到最后一个对象本身的所有成员。

考虑以下示例:

var Object1 = function (param) {
    this.prop1 = "p1 " + param;
    this.prop2 = "p2 " + param;
};

var Object2 = function (param) {
    Object1.apply(this, arguments);
    this.prop3 = 'p3' + param;
};

Object2.prototype = new Object1();

var b = new Object2('this is Object 2');

for (var v in b)
    print(v + ": " + b[v] + (b.hasOwnProperty(v)?' (own)':' (inherited)'));

此代码打印:

--prop1: p1 this is Object 2 (own)
--prop2: p2 this is Object 2 (own)
--prop3: p3this is Object 2 (own)

如果我看一下我看到的调试器:

b
  Object2
    prop1: "p1 this is Object 2"
    prop2: "p2 this is Object 2"
    prop3: "p3this is Object 2"
    __proto__: Object1

但是,我删除了apply 行,一切都更有意义了,但是基础对象没有初始化:

--prop3: p3this is Object 2 (own)
--prop1: p1 undefined (inherited)
--prop2: p2 undefined (inherited)

现在我在调试器中看到:

b
  Object2
    prop3: "p3this is Object 2"
    __proto__: Object1
      prop1: "p1 undefined"
      prop2: "p2 undefined"
      __proto__: Object

据我所知,apply 就像......执行超类构造函数,因此超成员被正确初始化,但显然这会改变子对象的形状。

为什么会这样?在 JS 中继承的正确方法是什么——或者至少不那么混乱?

我正在查看一些有关它的信息,显然每个开发人员对如何做都有不同的感受。

问候。

【问题讨论】:

标签: javascript oop inheritance prototypal-inheritance


【解决方案1】:

apply 一点也不像执行超类构造函数。作为一种构造,它执行任何函数在第一个提供的参数范围内。当您将 this 传递给您的 Object1 函数(您将其作为函数执行,而不是作为构造函数执行)时,您将通过正在执行第二个函数 (Object2) 的范围。

要查看发生了什么,请尝试执行Object1("param") 不使用 new

Object1("test");

当我们执行new Object1("test") 时,我们会得到一个如下所示的对象:

Object { prop1="p1 test", prop2="p2 test"}

但是当我们执行Object1("test") 时,我们会返回undefined ...并且在等于this 的对象上(在浏览器JavaScript 中很可能是window)我们发现了两个新变量...@ 987654336@和prop2

发生了什么?

这里的关键是:

Object1("param") !== new Object1("param");

第一个版本 (Object1("param")) 在一些已经存在的 范围内执行一个函数 (Object1)(在浏览器 JavaScript 中,最常见的范围是 this === window 所在的顶级范围。 ) 这是您在调用Object1.apply(this) 时调用Object1 的方式。

第二个版本 (new Object1("param")) 执行一个函数作为构造函数 - 也就是说,它创建一个 new 对象并将this 设置为该新对象.如果我们要使用相同的apply 函数来演示这一点,我们将编写Object1.apply({});

关于如何在 JavaScript 环境中进行类似 OOP 的编程正确,有关我所见过的最明确的答案之一,请参阅 Bobince's answer to this question

【讨论】:

  • 感谢一百万的解释。
猜你喜欢
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 2011-05-03
  • 2011-04-19
  • 1970-01-01
  • 2014-10-11
相关资源
最近更新 更多