7

我使用以下函数从一组参数创建 JavaScript 中的函数实例:

var instantiate = function (instantiate) {
    return function (constructor, args, prototype) {
        "use strict";

        if (prototype) {
            var proto = constructor.prototype;
            constructor.prototype = prototype;
        }

        var instance = instantiate(constructor, args);
        if (proto) constructor.prototype = proto;
        return instance;
    };
}(Function.prototype.apply.bind(function () {
    var args = Array.prototype.slice.call(arguments);
    var constructor = Function.prototype.bind.apply(this, [null].concat(args));
    return new constructor;
}));

使用上述函数,您可以按如下方式创建实例(参见小提琴):

var f = instantiate(F, [], G.prototype);

alert(f instanceof F); // false
alert(f instanceof G); // true

f.alert(); // F

function F() {
    this.alert = function () {
        alert("F");
    };
}

function G() {
    this.alert = function () {
        alert("G");
    };
}

上面的代码适用于用户构建的构造函数,例如F. Array但是,出于明显的安全原因,它不适用于本机构造函数。您可能总是创建一个数组,然后更改其__proto__属性,但我在 Rhino 中使用此代码,因此它不会在那里工作。有没有其他方法可以在 JavaScript 中实现相同的结果?

4

2 回答 2

7

你不能完全继承一个数组

但是,您可以使用它Object.create来消除当前代码 ( ex ) 中的许多复杂性。

于 2012-08-07T13:18:45.327 回答
3

我不认为你在这里实现了你想要的。首先在您的 F 和 G 函数中,您要在 this 对象上定义一个警报函数。这意味着每次实例化一个对象时,都会创建一个新的函数对象并将其分配给警报。这不是你想要的,你需要在 F 和 G 的原型上定义 alert。

function F() { }

F.prototype.alert = function() {
    alert("F");
};

function G() { }

G.prototype.alert = function() {
    alert("G");
};  

但是,您的实例化功能仍然存在问题。如果你按照你的方式称呼它

var f = instantiate(F, [], G.prototype);

你所做的只是将 f 的原型设置为 G.prototype,这不是我认为你想要的。我假设如果您实例化一个 F 对象,那么您将希望能够调用 F.prototype 上定义的所有函数,但事实并非如此。

function F() { }

F.prototype.alert = function() {
    alert("F");
};

F.prototype.foo = function() {
    alert("F foo");
};

function G() { }

G.prototype.alert = function() {
    alert("G");
};  


var f = instantiate(F, [], G.prototype);
f.foo(); // error!

这里错误的原因就像我说你只是将 f 的原型分配给 G.prototype 并且 G.prototype 没有定义 foo 函数。

如果您希望以这种方式进行继承,请查看 John Resig 的博客,他有一个很好的实现:http: //ejohn.org/blog/simple-javascript-inheritance/

道格拉斯·克罗克福德也整理了一些很好的例子:http ://www.crockford.com/javascript/inheritance.html

于 2012-08-08T21:38:01.863 回答