1

假设我有以下代码,我无法修改

var namespace = {};

function() {
    var MyConstructorFunction = function() {
        alert("default behavior");
    };

    namespace.MyConstructorFunction = MyConstructorFunction;

    setTimeout(function() {
        var instance = new MyConstructorFunction();
    }, 1000)
}();

我想在全局范围内从外部添加一些代码,我只能从这些代码中访问,namespace以便instance使用alert("custom behavior");

只是为了澄清我的意图,假设我可以想到这两种方法:

namespace.MyConstructorFunction = function() {
    alert("custom behavior");
};

或者

namespace.MyConstructorFunction.prototype.constructor = function() {
    alert("custom behavior");
};

但显然它们不起作用。有没有办法做到这一点?

4

2 回答 2

0

您可以使用原型链来覆盖命名空间中的方法。

// create an object that inherits from namespace
var o = Object.create(namespace);

// Override the MyConstructorFunction property
o.MyConstructorFunction = function ()  {
    alert("custom behavior");
}

您可以重用命名空间令牌

namespace = o;

或者,如果您愿意,可以使用不同的命名空间。

Object.create 是一个 ES5 特性,无法在 ES3 中完全模拟,但在这个用例中,它应该与基本的polyfill一起使用。


我知道你想从 setTimeout 调用不同的构造函数,在这个例子中这是不可能的。该函数引用了一个无法更改的局部变量。虽然您可以像本例中那样更改对象的全局行为,但您不能更改闭包内的变量,除非通过可以看到这些变量的函数。如果该函数要引用全局范围的变量而不是局部范围的变量,那么您会很幸运。

IE:

var namespace = {};

function() {
    var MyConstructorFunction = function() {
        alert("default behavior");
    };

    namespace.MyConstructorFunction = MyConstructorFunction;

    setTimeout(function() {
        var instance = new namespace.MyConstructorFunction(); // reference global
    }, 1000)
}();
于 2012-10-23T14:12:01.927 回答
0

如果是实例,则不能覆盖构造函数。在实际应用程序中,出于安全原因,您不希望这样做。

但是您可以覆盖或添加特定方法:

var F = function() {
  this.foo = 'bar';
}

var f = new F();
typeof f.foo; // "string"

f.foo = function() { return 'Bar' };
typeof f.foo; // "function"
于 2012-10-23T14:18:25.847 回答