2012-03-19 66 views
7

我不是一個很好的JavaScript用戶,但我可以用它完成任務。我對我用JavaScript編寫的代碼並不感到自豪,所以我決定改變它。這是我的第一步:JavaScript中良好範圍的方法

我想爲一個項目創建我自己的庫,下面是最初的結構。

window.fooLib = {}; 

(function (foo) { 
    "use strict"; 

    foo.doSomeStuff = function(param1) { 

     console.log(new AccommProperty(param1)); 
    } 

    //some internal function 
    function AccommProperty(nameValue) { 
     var _self = this; 
     _self.name = nameValue; 
    } 

}(fooLib)); 

我以前立即調用的函數表達式這裏來初始化我的變量。在這種情況下,它是fooLib

我不知道我是否應該做一些其他的事情,使window.fooLib更安全。我的意思是,如果我正確理解JavaScript,它可以被代碼運行後的任何其他代碼覆蓋。

你的想法是什麼?

+0

使用「use strict」;並保護你的對象,這就是你所能做的。 – Christoph 2012-03-19 09:03:40

+0

@Christoph我使用'「嚴格使用;」',如你所見。這是使用它的正確方式和地點嗎? – tugberk 2012-03-19 09:05:52

+2

是的。 [見john resig的文章](http://ejohn.org/blog/ecmascript-5-objects-and-properties/)關於如何實現保護或者https:// developer上的Object.freeze(obj) .mozilla.org/en/JavaScript/Reference/Global_Objects/Object/freeze – Christoph 2012-03-19 09:20:51

回答

1

如果要防止覆蓋變量,可以使用Object.defineProperty(),其中可寫:false,可配置:false。在你的情況下:

(function() { 
    "use strict"; 
    var foo = {}; 
    //some internal function 
    function AccommProperty(nameValue) { 
     var _self = this; 
     _self.name = nameValue; 
    } 
    foo.doSomeStuff = function(param1) { 

     console.log(new AccommProperty(param1)); 
    } 
    Object.defineProperty(window, "foolib", {value:foo}); 
}()); 

不過,這沒有什麼好的理由。它需要EcamScript 5.1才能工作,並且沒有墊片;也許可以用getters/setter來防止覆蓋=運營商。

但是,也不應該讓你的圖書館不可覆蓋。只是不要使用覆蓋lib的代碼。或者,也許有人甚至想用另一個更好的lib用相同的接口覆蓋你的函數?

如果問題是關於要共享的庫,可能與其他名稱空間衝突,則可以查看jQuery.noConflict

0

每個JavaScript對象都可以被重寫。這是JavaScript的本質,不可能改變它。所以你不能在這個意義上使你的代碼安全。

至於selfinvoked功能:你應該使用它們,當你想有局部變量,但viisible所有的功能。所以在你的情況下AccommProperty是這樣的變量。在範圍內定義doSomeStuff不會產生任何影響,除非doSomeStuff將使用範圍內定義的變量。

所以當你想隱藏用戶的變量和/或你需要全局變量而且你害怕名稱衝突使用selfinvoked函數。

+0

謝謝!改變了我的示例代碼。我認爲現在更有意義。 – tugberk 2012-03-19 08:57:20

-1

我不知道我是否應該做一些其他的事情,使window.fooLib更安全。我的意思是,如果我正確理解JavaScript,它可以被代碼運行後的任何其他代碼覆蓋。

您可以嘗試使window.fooLib爲局部變量。使用closures and nested functions一個可以模擬一個命名空間,你可以把你所有的數據,而不是將其放入全局範圍或將其連接到window對象:

(function() { 

    // all functions nested in foo() have access to fooLib. 
    fooLib = {} 

    fooLib.doSomeStuff = function(param1) { 
     console.log(param1); 
     console.log(fooLib); 
    } 

    //some internal function 
    function AccommProperty() { 
     console.log(fooLib); 
    } 

}()); 

詳情請參閱Javascript Closures: Encapsulating Related Functionality

+0

好的,但在這種情況下,我不能在這個IIFE之外使用'fooLib',如果我想創建一個庫,這沒什麼意義。或者我錯了? – tugberk 2012-03-19 08:59:20

+0

你的fooLib也被連接到了窗口中......並且你需要它來提供外部訪問(這是庫的意義?!)如果你不工作,你創建的任何對象(ES3)都可以被覆蓋與ES5並保護它。 – Christoph 2012-03-19 09:00:54

+0

@tugberk:將整個庫放在一個函數中,該函數將庫狀態保存爲局部變量。您的所有庫函數都成爲嵌套函數。 – 2012-03-19 09:06:14