我知道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);
答案 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中,因为这是特定于实现的)。所以这是true
:bar.__proto__ === com.foobar.Foo
。
继续前进,如果你希望bar
也是另一个对象的超类原型,你也会这样做:
var subbar = Object.create(bar);
有道理吗?如果您愿意,我稍后会添加更多关于Function
,属性prototype
和new
运算符的内容....
答案 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/