使用自定义原型实例化JavaScript函数

时间:2012-07-15 08:45:08

标签: javascript prototype instantiation

我使用以下函数从一组参数中创建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;
}));

使用上述功能,您可以按如下方式创建实例(请参阅fiddle):

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中实现相同的结果?

2 个答案:

答案 0 :(得分:6)

你不能fully subclass an array

但是,您可以使用Object.create从当前代码中删除大量复杂性(ex)。

答案 1 :(得分:3)

我认为你没有达到你想要的目标。首先在你的F和G中起作用 正在定义此对象的警报功能。这意味着每一次 实例化一个对象,将创建一个新的函数对象并将其分配给alert。 这不是你想要的,你需要在F和G的原型上定义警报。

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/

Douglas Crockford也提出了一些很好的例子:http://www.crockford.com/javascript/inheritance.html