2012-10-23 61 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" 
相關問題