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

Parameter variable in anonymous function in JavaScripts

本文关键字:参数 变量 JavaScripts 函数      更新时间:2023-09-26

我在Mozilla的JavaScripts教程中遇到了这个问题,我似乎无法理解。我读了很多堆叠式的问题,但找不到答案。下面给出了一个代码片段。

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

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

name被定义为类似于function( name /*<-- there it is */)的形式参数。

所以想想:

= function( name ) {
    var sex;
};

As:

= 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.