我找不到任何与我的确切问题匹配的内容,如果这是重复的,很抱歉。
给定代码:
var Foo = function () {
};
Foo.prototype.log = function (message) {
console.log(message);
};
var Bar = function () {
};
Bar.prototype = Object.create(Foo.prototype);
我可以在 Bar
中继承 Foo
的 log(message)
函数,并毫无问题地调用以下代码。
var bar = new Bar();
bar.log("this works");
如果我然后将原型(prototype)的分配移至构造函数,如下所示:
var Foo = function () {
};
Foo.prototype.log = function (message) {
console.log(message);
};
var Bar = function () {
Bar.prototype = Object.create(Foo.prototype);
};
调用log(message)
将会失败
TypeError: bar.log is not a function
现在我可能遗漏了一些明显的东西,但为什么会这样呢?我如何延迟继承属性?
我想象的用例是从异步加载的 JavaScript 文件继承对象,例如 google.maps.OverlayView
,同时页面中已经存在继承的对象。
最佳答案
当您在构造函数中分配原型(prototype)时,它将在第一次实例化之后分配。在代码片段(或 this jsfiddle 以及更多示例和继承检查)中,这种情况在 barfoo1
和 barfoo2
中进行了演示。解决方案是在 Bar
构造函数中复制 Foo.prototype
。另一个解决方案是在构造函数中分配原型(prototype)时返回一个实例。两者分别在代码段中的 FooBar
和 FooFoo
构造函数中进行了演示。
此外,您可以使用 Xyz.prototype = Abc.prototype
分配原型(prototype)(此处不需要 Object.create
),或使用 Xyz.prototype =新的Abc
。
var Foo = function () {};
Foo.prototype.log = function (msg) {
log(msg);
}
var Bar = function () {
Bar.prototype = Object.create(Foo.prototype);
};
var FooBar = function () {
if (!FooBar.prototype.log) {
for (var l in Foo.prototype) {
FooBar.prototype[l] = Foo.prototype[l];
}
}
}
var FooFoo = function () {
if (!FooFoo.prototype.log) {
FooFoo.prototype = new Foo;
return new FooFoo;
}
}
var BarFoo = function () {
if (!BarFoo.prototype.log) {
BarFoo.prototype = Object.create(Foo.prototype);
}
}
var bar = new Bar;
var foobar = new FooBar;
var barfoo1 = new BarFoo;
var barfoo2 = new BarFoo;
var doublefoo = new FooFoo;
try { bar.log('hello!'); }
catch(e) {log('bar.log failed => ', e.message);}
try { barfoo1.log('barfoo1 hello!'); }
catch(e) {log('barfoo1.log failed => ', e.message);}
try { barfoo2.log('barfoo2 hello!'); }
catch(e) {log('barfoo2.log failed => ', e.message);}
foobar.log('foobar just works (Foo.prototype copied)');
doublefoo.log('doublefoo just works too (instantiation on assigning Foo.prototype)');
function log() {
document.querySelector('#result')
.innerHTML += '<p>'+ [].slice.call(arguments).join('') +'</p>';
}
<div id="result"></div>
关于javascript - 原型(prototype)继承和构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28718150/