假设我有以下代码,我无法修改
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");
};
但显然他们不行。有没有办法做到这一点?
答案 0 :(得分: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调用一个不同的构造函数,在这个例子中是不可能的。该函数引用了一个无法更改的局部变量。虽然您可以像此示例中那样更改对象的全局行为,但除了可以查看这些变量的函数之外,您无法更改闭包内的变量。如果函数是引用全局范围的变量而不是本地范围的变量,那么你很幸运。
即:
var namespace = {};
function() {
var MyConstructorFunction = function() {
alert("default behavior");
};
namespace.MyConstructorFunction = MyConstructorFunction;
setTimeout(function() {
var instance = new namespace.MyConstructorFunction(); // reference global
}, 1000)
}();
答案 1 :(得分:0)
如果是实例,则不能覆盖构造函数。在实际应用程序中,出于安全原因,您不希望这样做。
但您可以覆盖或添加特定方法:
var F = function() {
this.foo = 'bar';
}
var f = new F();
typeof f.foo; // "string"
f.foo = function() { return 'Bar' };
typeof f.foo; // "function"