2012-09-11 82 views
1

我正在讀一本書,稍微高於我的水平。本書的作者正在展示如何使用匿名函數創建私人範圍。我理解私人範圍的概念,但是,我不明白它是如何實現的。我確實知道這些局部變量只能在當前作用域中訪問(這些是作者的話),但我不確定它將如何被調用/實現。你能不能給我一個例子爲如何將它在實際的代碼中使用使用var Tim = new Person();下面調用私人示波器

使用匿名函數來創建私有範圍:

var Person = function(){}; 

(function(){ 
    var findById = function(){ /* ... */ }; 
    Person.find = function(id){ 
    if (typeof id == "integer") 
     return findById(id); 
    }; 
})(); 

我的理解

var Tim = new Person(); 

會是什麼我打電話?我會試圖找到蒂姆的身份證嗎?

+0

其實,我嘗試了一些類似於你的代碼,它不起作用。我通過將'Person.find'更改爲'Person.prototype.find'來修復它。使用這樣的匿名函數是擁有私有類成員的絕佳方式,或者至少提供私有類成員提供的所有內容。我很驚訝Crockford沒有提到它。 – GreatBigBore

回答

0

你會打電話findById只能間接通過調用Person.find

// Assuming code similar to your code above 
// Assume that Tim.id === 1 
var someone = Person.find(1); // Call findById to get a reference to Tim 
console.log(someone.name); // Tim 
findById(1) // Error, findById is not available in the global scope 
3

首先:您所提供的代碼片段將不會返回ID,但是當通過一個ID將返回的東西。我必須承認,就私人範圍而言,這個例子並不是最好的例子。我會給你一個更詳細的,但我希望更清晰的例子:

(function() 
{ 
    var personObjects = []; 
    var findById = function(id) 
    { 
     return personObjects[id]; 
    } 
    var Person = function (name) 
    { 
     this.id = personObjects.length;//first available index ~= auto increment 
     this.name = name; 
     personObjects.push(this); 
    }; 
    Person.find = function(id) 
    { 
     //I woudl do: id = +id;, but sticking to your example 
     if (typeof id === 'number') 
     { 
      return findById(id); 
     } 
     return undefined; 
    } 
    window.Person = Person;//expose to global object 
})(); 

那麼,我們在這裏有什麼。你說你瞭解範圍,所以我假設你知道在這裏聲明的所有變量都會在包裝函數返回後依然生存,但是它們只對在同一範圍內聲明的函數可見。如果不是:personObjects數組和findById函數對象仍然存在,但只能由Person構造函數訪問,該構造函數公開(因爲已分配)全局對象。

我使用數組的長度來確定下一個可用的ID,無論何時一個人對象被實例化,從而爲每個對象創建一個唯一的ID。當你傳遞一個有效的id(數組鍵)給它時,函數findById只是返回一個對象的引用。 Person.find方法調用這個封閉的函數,但是在這之前對參數進行一些檢查。在某些特定的情況下,這可以用於調試,或者在長原型鏈中使用泛型設置器和獲取器。這就是爲什麼,對我來說,至少,這個例子有點牽強附會。

總之,你叫喜歡所以這個私有方法(findById):

var tim = new Person('tim'); 
Person.find(0);// returns a reference to tim 
//or even 
var tom = new Person('Tom'); 
tim.find(1);//returns tom 
tom.find(0);//returns tim 
tim.find(tom.id);//... 

同樣,這種做法是不是太常見據我所知,練習/習慣範圍和封鎖我建議一些工作與setInterval和事件代表團的魔術(例如:嘗試在移動設備上爲tab事件創建您自己的代理人)。只要谷歌他們,你很快就會明白爲什麼這是一個很好的鍛鍊,但起初有點令人生畏。

+0

非常感謝。現在更清楚了。 – Leahcim