原型继承和构造函数

时间:2015-02-25 11:42:53

标签: javascript inheritance

我无法找到与我的确切问题相符的内容,如果这是重复的话,请对不起。

鉴于代码:

var Foo = function () {
};

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

var Bar = function () {
};

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

我可以继承log(message)Foo的{​​{1}}函数,并且可以毫无问题地调用以下代码。

Bar

如果我然后将原型的赋值移动到构造函数中,如下所示:

var bar = new Bar();

bar.log("this works");

var Foo = function () { }; Foo.prototype.log = function (message) { console.log(message); }; var Bar = function () { Bar.prototype = Object.create(Foo.prototype); }; 的调用将失败

  

TypeError:bar.log不是函数

现在我可能遗漏了一些明显的东西,但为什么会这样呢?我如何懒惰地继承属性?

我想象的用例是从异步加载的JavaScript文件继承对象,类似于log(message),同时能够在页面中存在继承的对象。

2 个答案:

答案 0 :(得分:1)

在构造函数中分配原型时,将在首次实例化后分配。在代码段(或this jsfiddle以及更多示例和继承检查)中,barfoo1barfoo2演示了这种情况。解决方案是在Foo.prototype构造函数中复制 Bar。另一种解决方案是在构造函数中返回一个实例来分配原型。两者都分别在代码段中的FooBarFooFoo构造函数中进行了演示。

此外,您可以仅using Xyz.prototype = Abc.prototype分配原型(此处不需要Object.create),或使用Xyz.prototype = new 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>';
}
&#13;
<div id="result"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

詹姆斯如果你的代码中有jQuery是可行的,你可以尝试这样的事情 -

var Bar = function() {};
$.ajax({
  url: "http://maps.google.com/api/scriptfile.js",
  dataType: "script",
  success: function(script, status) {
             Bar.prototype = Object.create(Foo.prototype);
           }
});

希望这有帮助!