javascript - 原型(prototype)继承和构造函数

标签 javascript inheritance

我找不到任何与我的确切问题匹配的内容,如果这是重复的,很抱歉。

给定代码:

var Foo = function () {
};

Foo.prototype.log = function (message) {
    console.log(message);
};

var Bar = function () {
};

Bar.prototype = Object.create(Foo.prototype);

我可以在 Bar 中继承 Foolog(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 以及更多示例和继承检查)中,这种情况在 barfoo1barfoo2 中进行了演示。解决方案是在 Bar 构造函数中复制 Foo.prototype。另一个解决方案是在构造函数中分配原型(prototype)时返回一个实例。两者分别在代码段中的 FooBarFooFoo 构造函数中进行了演示。

此外,您可以使用 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/

相关文章:

javascript - 如果点击取消按钮,如何拒绝输入框中的任何更改?

javascript - Angular 动态选择值

javascript - 尝试在按键上构建带动画启动的下拉菜单

inheritance - 如何在 React 组件和 es6 类中使用继承

Java 泛型 : override method that differs in parameterized return type

c++ - 使用 C++ 通过继承组织树复制

javascript - 如何组合两个init函数?

javascript - 使表中的整行 float ,同时保持所有其他行就位

java - 用Java中的通用参数覆盖方法?

c++ - 无需显式初始化父类的虚拟继承