2012-10-23 35 views
1

比方说,我有下面的代码,这我不能修改有没有办法从JavaScript中的引用覆盖构造函数?

var namespace = {}; 

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

    namespace.MyConstructorFunction = MyConstructorFunction; 

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

我想在全球范围内从中我只能访问namespace制作instance与构建外部添加一些代码alert("custom behavior");

只是为了澄清我的意图,让我们说,我可以认为这两个aproaches的:

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

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

但显然他们没有工作。有没有办法做到这一点?

+2

如果你说你想改变公司在'setTimeout'调用,则没有构造函数。那里使用的变量对立即调用的函数是本地的。你不能碰那个变量,而且函数本身是不可变的,所以真的没有办法做到这一点。 –

回答

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) 
}(); 
+2

这不影响赋值给OP询问的变量'实例'。而设置'o.prototype'对继承没有任何影响。 'o'不会从'namespace'继承其余的项目。 –

0

如果它是一个实例,你不能覆盖的构造。在实际的应用程序中,出于安全原因您不希望出现这种情况。

但是你可以重写或添加特定的方法:

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

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

f.foo = function() { return 'Bar' }; 
typeof f.foo; // "function" 
相关问题