2013-02-17 58 views
0

我有以下格式的命名空間,允許公共和私有成員:如何附加到從閉包創建的JavaScript命名空間?

function A() { 
    return('a'); 
} 

namespace1 = (function() { 
    // private 
    namespace2 = (function() { 
     // private 
     prC = function() { 
      return(namespace1.puB() + 'c'); 
     }; 
     puC = function() { 
      return(prC()); 
     }; 
     // public 
     return({ 
      puC: puC 
     }); 
    })(); 
    prB = function() { 
     return(A() + 'b'); 
    }; 
    puB = function() { 
     return(prB()); 
    }; 
    // public 
    return({ 
     puB: puB, 
     namespace2: namespace2 
    }); 
})(); 

document.write('A() = '); try { document.write(A()); } catch (ex) { document.write('inaccessible'); } 
document.write('<BR />'); 
document.write('namespace1.prB() = '); try { document.write(namespace1.prB()); } catch (ex) { document.write('inaccessible'); } 
document.write('<BR />'); 
document.write('namespace1.puB() = '); try { document.write(namespace1.puB()); } catch (ex) { document.write('inaccessible'); } 
document.write('<BR />'); 
document.write('namespace1.namespace2.prC() = '); try { document.write(namespace1.namespace2.prC()); } catch (ex) { document.write('inaccessible'); } 
document.write('<BR />'); 
document.write('namespace1.namespace2.puC() = '); try { document.write(namespace1.namespace2.puC()); } catch (ex) { document.write('inaccessible'); } 

輸出:

A() = a 
namespace1.prB() = inaccessible 
namespace1.puB() = ab 
namespace1.namespace2.prC() = inaccessible 
namespace1.namespace2.puC() = abc 

我怎麼可能去公共和私有成員追加到這樣一個命名空間(IE :來自不同的文件)?

Here's a JSFiddle

+0

這只是一堆返回對象的自調用函數,問題是返回的對象不包含您試圖訪問的屬性,沒有這樣的東西來刪除JS中的私有或公有。要將更多方法添加到對象中,只需使用點或括號表示法進行操作,並且可以對函數進行原型設計。因爲你沒有用'var'關鍵字去掉這些變量,所以它們是全局變量,並且可以在窗口範圍內訪問,參見[** FIDDLE **](http://jsfiddle.net/qQtGA/1/) ??? – adeneo 2013-02-17 02:23:18

+0

在你的上下文中,'prB()'根本不是私有的。它是全球性的。嘗試運行'prB()'! – Amberlamps 2013-02-17 02:33:13

回答

2

「我怎麼可能去公共和私有成員追加到這樣一個命名空間......」

那麼,你的功能被曝光,因爲你沒有正確地聲明變量var

但是,一旦你解決這個問題,你可以從可以引用您namespace對象的任何代碼,添加更多的暴露性質(因爲所有的屬性都暴露)


添加引用本地(適當的期限爲私人)功能更多的屬性,你需要一個新的函數和變量的作用域。

只需調用引用namespace對象的函數,在該函數內創建一些函數,然後添加引用這些本地函數的屬性。

// Other file 

(function() { 
    var newLocalFunc = function() { 
     // local function 
    } 

    var anotherLocalFunc = function() { 
     // local function 
    } 

    namespace1.exposedFunc = function() { 
     return newLocalFunc() 
    } 
    namespace1.namespace2.anotherExposedFunc = function() { 
     return anotherLocalFunc() 
    } 
})(); 

並再次,不要忘記把你的var變量之前在原來的代碼。

1

任何變量聲明沒有var關鍵字將在全球範圍內。所以你的puB()函數是不可訪問或私有的,它只是不是由namespace1函數返回的對象的成員。例如,嘗試window.prB(),您會看到該方法存在於window對象的全局範圍內。

<head> 
    <script type="text/javascript"> 
     obj1 = {}; //in global scope 
     var obj2 = {}; //in global scope. Although used the var keyword, this line itself is in the global scope; so the variable. 
     function someFunc() { 
      obj3 = {}; //in global scope 
      var obj4 = {}; //'so-called' private (inaccessible from global scope) 
     } 
    </script> 
</head> 

對於在相同的 '命名空間' 組合兩種不同的JS文件(或假設對象):

文件-1的.js

var namespace1 = (function() { 
    // some code... 
    var namespace2 = (function() { 
     // some code... 
     return { 
      obj2: 'value2' 
     }; 
    })(); 

    return { 
     obj1: 'value1' 
    }; 
})(); 

文件-2。JS

namespace1.namespace3 = (function() { 
    // some code... 
    var ns4 = (function() { 
     // some code... 
     return { 
      obj4: 'value4' 
     }; 
    })(); 

    return { 
     obj3: 'value3', 
     namespace4: ns4 
    }; 
})(); 

的是什麼:

  • namespace1在全球範圍內聲明;所以從任何地方都可以訪問 ,這是我們的主要目標。
  • namespace2無法訪問(私人)。
  • namespace3在全球範圍內無法訪問,但可作爲namespace1的 成員訪問;例如:​​。
  • ​​可作爲namespace1的成員訪問。例如: namespace1.namespace4

所以;我們的主要對象namespace1的成員是:

namespace1 = { 
    obj1: String, 
    namespace3: { 
     obj3: String, 
     namespace4: { 
      obj4: String 
     } 
    } 
}; 
0

您是來自堪薩斯州很長的路要走,在這裏。

你不能「公開」或「私下」聲明事物。
只要你在函數內定義了一些東西,然後選擇返回特定的東西,或者將它們追加到作爲參數傳入的對象/數組中,那麼你將擁有對這些東西的「公共」(外部)訪問權限,函數返回後。

爲了獲得「私人」訪問權限,您將返回一個引用內部內容的函數。

var Wallet = function (amount, overdraft_limit) { 
    var balance = 0, 
     overdraft = overdraft_limit || 0, 

     deposit_funds = function (funds) { balance += funds; return true; }, 

     withdraw_funds = function (request) { 
      var funds = 0; 
      balance -= request; 
      funds = request; 
      return funds; 
     }, 

     validate_request = function (pin) { /* ... */ }, 

     sufficient_funds = function (val) { return val <= (balance + overdraft); }, 

     add = function (pin, deposit) { 
      if (!validate_request(pin) || deposit <= 0) { return false; } 

      var result = deposit_funds(deposit); 
      return result; 
     }, 

     deduct = function (pin, withdrawl) { 
      if (!validate_request(pin) || withdrawl <= 0) { return false; } 
      if (!sufficient_funds(withdrawl)) { return false; } 

      var funds = withdraw_funds(withdrawl); 
      return funds; 
     }, 

     check = function() { return balance; }, 

     public_interface = { deduct : deduct, add : add, check : check }; 

    return public_interface; 
}; 


var myWallet = Wallet(30, 20); 

var cash = myWallet.deduct(40); 
cash;    // 40 
myWallet.check(); // -10 

myWallet.balance = 40000000000; 

cash = myWallet.deduct(4000); 
cash; // === false 

通過建立我的「構造」,即有機會獲得balance,我返回「公共」對象可以調用方法與「私有」的數據進行交互變量的內部功能,但不能訪問它或通過任何方法修改它,但使用這些「公共」功能。

嵌套這個東西8層深,使用IIFEs使用我剛剛演示的完全相同的閉包概念。

明確地決定你將要返回什麼,你不是什麼。
您發送到世界的功能是public。函數內部沒有被返回或附加到對象的函數/ etc是私有的。
它們已經被返回的「構造函數」函數關閉了,現在它們是100%不可訪問的,除了使用構造函數內部構建的函數,該函數引用私有變量並作爲公共方法返回。