这是子类还是新实例?

时间:2013-10-25 23:49:49

标签: javascript oop

我知道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”}});

..但是禁止Foo的子类型或Foo的实例?我倾向于Foo的例子,因为以下打印'undefine'

  

的console.log(bar.prototype);

3 个答案:

答案 0 :(得分: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成为另一个prototype Foo的对象。这意味着可以在Foo上使用bar所有内容,例如bar.bar === 'bar'(如果这有意义)。对Foo的更改将反映在bar中,但不会反映在{{1}}中。它不是完全一个子类型。 (JS很奇怪,但它很令人愉快。)

有关详情,请查看MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

答案 1 :(得分:1)

Javascript没有类,只有对象。创建对象时,它还可以有原型只是另一个对象,创建的对象将用于委派对属性的调用(或功能)它本身并不理解。

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

因此,在取得这一领先优势时,您希望Foo为您创建的其他对象制作原型; Foo有点像对象的超类。

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

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

这意味着bar将拥有Foo的原型,并且buz还将拥有拥有属性(即不在原型中)。< / p>

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

继续前进,如果你希望bar也是另一个对象的超类原型,你也会这样做:

var subbar = Object.create(bar);

有道理吗?如果您愿意,我稍后会添加更多关于Function,属性prototypenew运算符的内容....

答案 2 :(得分:0)

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

// 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/