0

我在 Mozilla 的 JavaScript 教程中遇到了这个问题,但我似乎无法理解。我阅读了很多 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,但不知何故,pet并且pet2表现得像一个类的对象,具有一个名为的成员变量name和一堆成员函数getName()setName()等等。这是如何工作的?

4

2 回答 2

3

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

于 2012-08-25T06:34:25.340 回答
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

于 2012-08-25T07:23:07.620 回答