2012-08-25 109 views
0

我在Mozilla的JavaScript教程中遇到了這個問題,我似乎無法理解它。我讀了很多stackoverflow的問題,但我找不到我的問題的答案。下面給出的是一段代碼片段。JavaScript中的匿名函數中的參數變量

var createPet = function(name) { 
    var sex; 

    return { 
    setName: function(newName) { 
     name = newName; 
    }, 

    getName: function() { 
     return name; 
    }, 

    getSex: function() { 
     return sex; 
    }, 

    setSex: function(newSex) { 
     if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) { 
     sex = newSex; 
     } 
    } 
    } 
} 

var pet = createPet("Vivie"); 
var pet2 = createPet("Sam"); 
pet.getName();     // Vivie 
pet2.getName();     // Sam 

createPet似乎只返回地圖功能的對象,但沒有可變name提及任何地方,但不知何故,petpet2的行爲很像一個名爲name成員變量和一堆的成員函數的類的對象像getName(),setName()等。這是如何工作的?

+0

'name'和'sex'是正常變量,不是任何對象的成員。認爲他們是一個對象的成員只會導致更多的混淆。對象屬性和變量之間存在巨大差異。 – Esailija

回答

3

namecreatePet()函數的參數。它與局部變量sex的作用相同,並且作爲私有成員變量運行,該變量只能在createPet()內聲明的函數訪問。 name傳遞到createPet(),但它也可以在createPet()之內設置,並且由於返回對象中的函數創建的閉包存在,所以它可以在createPet()的執行中存活,所有函數都引用了name參數。

+0

確定那種有意義的除了這裏createPet是一個匿名函數。這裏看起來createPet()的行爲就像一個對象的構造函數。所以每次調用createPet()時,都會創建一個新的名稱和性別變量以及所有關聯的方法。那是對的嗎? – BegaluruBoy

+0

@BegaluruBoy - 'createPet'不是匿名的 - 它是一個包含函數的變量。該函數創建並返回一個具有許多函數作爲屬性的對象。由於閉包,這些函數可以在其範圍內作爲變量訪問'sex'和'name',它們可以讀取/更改,並且它們存在於每個實例中,因此它們像成員變量一樣工作,但是它們是私有的。是的,它的行爲像一個構造函數。它實際上更像是一個工廠函數,因爲你不用'new'來使用它。你稱它爲它並創建一個對象。 – jfriend00

+0

對不起,您是對的。它不是一個匿名函數。更高層次的問題。這看起來非常直觀。它背後的理由是什麼? – BegaluruBoy

0

name被定義爲形式參數,如function(name /*<-- there it is */)

於是想到:

= function(name) { 
    var sex; 
}; 

由於:

= function() { 
    var name = arguments[0]; 
    var sex; 
} 

他們的確是完全相同,或者至少相當於同一。

是的,createPet返回混雜封閉的啞圖。事實上,你可以做到這一點,看看它仍然可以工作:

var a = createPet("Vivie"); 

var asd = a.setName; 

asd("asd"); 

a.getName() //"asd" 

這是因爲對象是非常不相關的,它是承載數據不是對象的功能。該對象只是一個愚蠢的函數映射(閉包)。

你也不會處理對象屬性而是處理變量。你不能假裝變量是對象的屬性,除非它是一個全局變量。它實際上不是一個變量,但全球對象的屬性:

  • 屬性可以枚舉,動態訪問,刪除和恆定
  • 屬性可以在任何地方訪問,只要你有一個對象的引用

最重要的是,整個模型是倒退的。你有行爲承載數據而不是攜帶行爲的數據。

您當然不必這麼做,請參閱https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model