0

我知道 JavaScript 继承与典型的 OO 语言(Java、c++ 等)有很大不同。环顾四周,似乎也有许多不同的方法来创建类和类层次结构。因此,我对 JavaScript 继承感到困惑。

给定以下代码

if (!com) var com = {};
if (!com.foobar) com.foobar = {};

com.foobar.Foo = {
        foo : "foo",
        bar : "bar",
        baz : function () {
        return true;
        }
};

为什么不允许以下内容?为什么 com.foobar.Foo 不是构造函数?是不是因为 Foo 不是一个函数,而是一个对象?

var baz = new com.foobar.Foo();

既然我不能做上述事情,我将如何创建一个新的 Foo?

如果我想扩展 Foo,我想我会这样做:

var bar = Object.create(com.foobar.Foo, {buz: {value: "neat"}});

.. 但是 bar 是 Foo 的子类型还是 Foo 的实例?我倾向于 Foo 的实例,因为以下打印件是“未定义”

console.log(bar.prototype);

4

3 回答 3

2

你是对的,你不能这样做,var baz = new com.foobar.Foo();因为Foo它是一个对象,而不是一个函数。

Object.create用于设置变量的原型(即bar.prototype = Object.create(/*etc etc*/))。有关更多信息,请参阅 MDN 页面:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

正确使用Object.create会导致bar成为另一个具有prototypeof 的对象Foo。这意味着任何东西Foo都可以用于bar, 例如bar.bar === 'bar'(如果有意义的话)。的更改Foo将反映在 中bar,但反之则不会。它不是一个亚型。(JS 很奇怪,但令人愉快。)

有关这方面的更多信息,请查看 MDN:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

于 2013-10-25T23:57:40.023 回答
1

Javascript没有类,只有对象。当你创建一个对象时,它也可以有一个原型,它只是另一个对象,创建的对象将使用它来委托对它本身不理解的属性(或函数)的调用。

这或多或少类似于经典继承,因为子类也将它不理解的调用委托给超类。

因此,带头,您想Foo为您创建的其他对象制作原型;Foo会有点像对象的超类。

您已经知道的一个方便的功能是Object.create. 您可以使用它来创建具有特定原型的新对象,就像您所做的那样:

var bar = Object.create(com.foobar.Foo, {buz: {value: "neat"}});

这意味着bar将拥有 的原型,Foo并且还将拥有自己的属性(即不在原型中)buz

bar现在,可以在属性 上找到指向的原型Foo(至少在 Chrome 中,因为这是特定于实现的)__proto__。所以这是truebar.__proto__ === com.foobar.Foo

展望未来,如果您还想bar成为另一个对象的超类原型,您也可以这样做:

var subbar = Object.create(bar);

说得通?如果你愿意,我稍后会添加更多关于Function, 属性prototypenew操作符的信息......

于 2013-10-26T00:24:34.580 回答
0

您无法实例化 Foo 因为它是一个对象,而不是一个函数。您可以通过创建一个函数并使用原型设置实例方法来实现:

// constructor method
com.foobar.Foo = function() {
    this.foo = 'foo'
    this.bar = 'bar'
}

com.foobar.Foo.prototype.baz = function() {
    return true
}

看看它在 jsfiddle 上运行:http: //jsfiddle.net/DE7KZ/

于 2013-10-25T23:55:30.767 回答