JavaScripts中匿名函数中的参数变量

时间:2012-08-25 06:31:46

标签: javascript closures

我在Mozilla的JavaScripts教程中遇到过这个问题,我似乎无法理解它。我读了很多stackoverflow问题,但我找不到我的问题的答案。以下是代码段。

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()等。这是如何工作的?

2 个答案:

答案 0 :(得分:3)

namecreatePet()函数的参数。它与局部变量sex的工作方式相同,并且表现为私有成员变量,只能在createPet()内声明的函数访问。 name被传递到createPet(),但它也可以在createPet()内设置,并且由于返回对象中的函数创建的闭包,它在createPet()的执行中幸存这些都引用了name参数。

答案 1 :(得分: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