2017-01-17 58 views
0

我讀this一篇關於JavaScript的模塊模式和跨聲稱可以保護私有變量/函數跨模塊文件和相互訪問它們的一個片段來了:如何在Javascript模塊模式中使用私有函數/變量?

var MODULE = (function (my) { 
    var _private = my._private = my._private || {}, 
     _seal = my._seal = my._seal || function() { 
      delete my._private; 
      delete my._seal; 
      delete my._unseal; 
     }, 
     _unseal = my._unseal = my._unseal || function() { 
      my._private = _private; 
      my._seal = _seal; 
      my._unseal = _unseal; 
     }; 

     // permanent access to _private, _seal, and _unseal 

    return my; 
}(MODULE || {})); 

我有點困惑至於我如何去實現這一點,但我認爲大部分的困惑都來自於不瞭解它是如何工作的;它如何使已經加載的其他腳本能夠利用這些內部值?如何在這個「私人」空間中添加函數和變量?

我的最終目標是提供一種'抽象'函數變量,必須在子模塊中重寫,但仍需要在基本模塊的文件中引用。無可否認,我還沒有玩過這麼多,但主要是因爲我試圖圍繞實際實施如何運作。

我想的是類似以下內容,但它似乎並沒有工作,因爲它不能訪問內部功能:提前

// Preserve state of private variables/functions across modules 
    var _private = my._private = my._private || {}, 
     _seal = my._seal = my._seal || function() { 
      delete my._private; 
      delete my._seal; 
      delete my._unseal; 
     }, 
     _unseal = my._unseal = my._unseal || function() { 
      my._private = _private; 
      my._seal = _seal; 
      my._unseal = _unseal; 
     }; 

    my._private._unseal(); 

    my._private.bindEvents = function() { 
     alert("This function should be re-declared in your sub-module."); 
    }; 

    my._private._seal(); 

感謝。

回答

0

我的最終目標是提供一種「抽象」函數變量是 必須在子模塊覆蓋,但仍需要在 基本模塊的文件引用。無可否認,我還沒有玩過這麼多,但主要是因爲我試圖圍繞實際的 實現如何工作。

首先,前進。 JavaScript不是傳統的面向對象的編程語言。

在JavaScript中,如果你想做的東西,如果它被定義,你可以這樣做:

// Look at entire prototype chain for a function 
if("doStuff" in obj) { 
    obj.doStuff(); 
} 

// Or just check if the own object has the whole function 
if(obj.hasOwnProperty("doStuff")) { 
    obj.doStuff(); 
} 

作爲私人的事或任何支持JavaScript的知名度,所有你可能會發現周圍的淨只是技巧,因爲目前的JavaScript沒有訪問修飾符。

無論如何,您的樣品添加_seal_private性質my其通常被稱爲exports,並定義了添加屬性設置到這些頂層屬性的對象是私有的或按照慣例密封。所以,是的,這只是一個約定:不要訪問屬於從模塊外部設置爲_private的對象的部分屬性...

順便說一句,我的兩毛錢在這裏是你應該避免這種情況並使用JavaScript 一樣,並處理沒有訪問修飾符的事實。同時,ECMA-Script 2015及以上版本定義了一種新方法來聲明屬性,該屬性的名稱是唯一標識符symbols。如果你沒有自己的符號,你不能訪問全屬性:

let sampleSymbol = Symbol("sample symbol"); 
let sampleSymbol2 = Symbol("sample symbol 2"); 

var obj = { 
    // Defines the property with a symbol during object 
    // declaration 
    [sampleSymbol]: "hello world" 
}; 

// Defines the property using regular property declaration syntax 
// once the object has been already built 
obj[sampleSymbol2] = "goodbye!"; 

現在使用模塊模式導出這個對象和其他模塊將無法訪問在一個簡單的全屬性這反過來很好地模擬財產訪問私人修改。

最糟糕的是,你仍然可以得到使用Object.getOwnPropertySymbols功能給定對象的符號,但符號不是像Array.prototype.forEach(...)for..inObject.keys(...),或for..of迭代器的一部分,所以你應該去了。

相關問題