2012-11-27 109 views
2

可能重複:
Javascript outer scope variable access的JavaScript模塊私有內部函數可以訪問 「這個」 範圍

我有一個JavaScript模塊,看起來像下面。我遇到的主要問題是如何從私人someOtherFunc訪問「此」範圍中的變量。有私人someOtherFunc

var mymodule = (function(){ 

    return { 
     MyObj : function() { 

      this.myvar = 123; 

      this.publicfunc = function() { 
       someOtherFunc(); 
      }; 

      var someOtherFunc = function() { 
       //this doesn't seem to work 
       this.myvar = 456; 
      }; 

     } 
    } 
} 

的想法來訪問this.myvar一種方式,我希望能夠像做

new mymodule.MyObj().publicfunc,但使someOtherFunc私人

+0

'someOtherFunc.call(this)'而不是'someOtherFunc()'。 –

回答

2

忘了我以前的答案。你可以這樣做只是通過添加一個私人版這個

var mymodule = (function() { 
    return { 
     MyObj : function() { 
      this.myvar = 123; 
      var that = this; 

      this.publicfunc = function() { 
       someOtherFunc(); 
      }; 

      var someOtherFunc = function() { 
       that.myvar = 456; 
      }; 
      return this; 
     } 
    }; 
}); 
記住

熊,憑你的代碼,每次通話時間MyObj中你得到一個新的對象
所以這會做你想要什麼:

>var o = new mymodule().MyObj() 
>o.myvar 
123 
>o.publicfunc() 
>o.myvar 
456 

,但不是這個

>var m = new mymodule() 
>m.MyObj().myvar 
123 
>m.MyObj().publicfunc() 
>m.MyObj().myvar 
123 

如果這不是你想要的,可考慮做這樣的事情

var mymodule = (function() { 
    var myObj = null; 
    this.MyObj = function() { 
     if(myObj != null) 
      return myObj; 
     myObj = {}; 
     myObj.myvar = 123; 

     myObj.publicfunc = function() { 
      someOtherFunc(); 
     }; 

     var someOtherFunc = function() { 
      myObj.myvar = 456; 
     }; 
     return myObj; 
    }; 
}); 
+0

但是現在someOtherFunc是一個公共函數,對不對?我不希望MyObj的實例能夠訪問某些OtherFunc –

+0

@JeffStorey查看我答案中的更改。 – Yandros

0

你不return任何從MyObj

return this; 

應該修復它。

+0

似乎沒有這樣做 –

0

使用綁定方法:

var someOtherFunc = function() { 
    this.myvar = 456; 
}.bind(this); 
1

爲什麼不建立它有點刻意?

// this one returns an object used like: 
// myModule.myInt; /* 456 */ 
// myModule.myFunc(); /* 124 */ 
var myModule = (function() { 
    var secretData = 123, 
     publicData = 456, 

     publicFunc = function() { return privateFunc(secretData); }, 
     privateFunc = function (num) { return num + 1; }, 

     public_interface = { 
      myInt : publicData, 
      myFunc : publicFunc 
     }; 

    return public_interface; 

}()); 

我通過明確命名的返回,公共對象的麻煩去,但它現在已經非常清楚是什麼,是不公開的,然而,這些東西每個人將有機會獲得的變量版本除了一個例外,如果你改變myModule.myIntpublicData,它們將不再相等。


爲了證明我的意思在下面的意見,創建自己的私有數據/方法的多個實例,我只添加的功能範圍內多了一個層:

var myModule = (function() { 

    var static_int = 789, 

     makeInstance = function (/* any constructor values */) { 
      var secretData = 123, 
       publicData = 456, 

       publicFunc = function() { return privateFunc(secretData); }, 
       privateFunc = function (num) { 
        console.log(static_int); 
        return num + 1; 
       }, 

       public_interface = { 
        myInt : publicData, 
        myFunc : publicFunc 
       }; 

      return public_interface; 
     }; 

    return makeInstance; 
}()); 

您現在使用它像:

var newModule = myModule(/* instance parameters */); 
newModule.myFunc(); 

...或

var num = myModule(/* instance parameters */).myFunc(); 

如果你想節省內存,你可以有靜態輔助功能靜電層內部:

var myModule = (function() { 

    var static_int = 789, 

     static_addOne = function (num) { return num + 1; }, 
     static_divideBy = function (dividend, divisor) { return dividend/divisor; }, 

     makeInstance = function (/* any constructor values */) { 
      var secretData = 123, 
       publicData = 456, 

       publicFunc = function() { return privateFunc(secretData); }, 
       privateFunc = function (num) { 
        console.log(static_int); 
        return num + 1; 
       }, 

       public_interface = { 
        myInt : publicData, 
        myFunc : publicFunc 
       }; 

      return public_interface; 
     }; 

    return makeInstance; 
}()); 

現在你有隻寫一個「私」功能時間(即:節省內存),但任何實例都可以使用這些函數。

這裏的漁獲:
由於範圍和封閉的工作方式,靜態功能有NO訪問值的實例(函數內部可以訪問靜態函數中,而不是相反)。

因此,任何靜態輔助功能MUST必須傳遞給它們的參數的值,如果你正在修改一個數字或字符串,你MUST的價值迴歸這一職能的。

// inside of a private method, in any instance 
var privateString = "Bob", 

    privateFunc = function() { 
     var string = static_helper(privateString); 
     privateString = string; 
     //... 
    }; 
+0

但是,如果public_interface的每個實例都需要它自己的secretData呢? –

+0

然後把所有內部的東西放入一個函數中,並返回函數,除非你還需要「靜態」數據,在實例之間共享,在這種情況下,你將在外部函數中定義「靜態」變量,然後從您返回的函數(構建實例)中引用它們。 – Norguard

+0

在這種情況下,privateFunc可以訪問secretData嗎? (如果myModule的每個實例都有secretData)?你能舉出一個如何完成的例子嗎? –

1

聲明myvar使用var關鍵字,使其成爲私人,然後訪問它沒有this.

function MyObj(){ 

     var myvar = 123; 

     this.publicfunc = function() { 
      someOtherFunc(); 
     }; 

     var someOtherFunc = function(){ 

      alert(myvar); 

     };    
} 


var o = new MyObj(); 
o.publicfunc(); 

如果需要myvar公共訪問然後創建一個公共的getter/setter。

jsFiddle Demo

1

我認爲你在尋找什麼是封裝myvar更改的方式。當某些其他答案運行時,myvar通常將保持爲123,因爲最初從mymodule返回的對象會保持該初始值。

返回一個函數,該函數即使在修改後也能得到myvar的值,我認爲這有助於解決問題。

下面是對我的作品的代碼:

var mymodule = (function(){ 
    var myvar = 123, 
     publicfunc = function() { myvar = 456 }, 
     getMyVar = function() { return myvar; }; 

    return { 
     someOtherFunc : publicfunc, 
     myPublicVar : getMyVar 
    }; 
}()); 

mymodule.someOtherFunc(); 
alert(mymodule.myPublicVar());​ //gives you 456 

的jsfiddle here

我希望這會有所幫助。

相關問題