关于javascript:在准备70-480微软考试时,我需要帮助理解为什么一个?swer是正确的

In preparing for 70-480 Microsoft exam, I need help understanding why an a?swer is Correct

使用下面的代码,customer.name是未定义的。 有人可以帮我理解为什么以及代码发生了什么?

1
2
3
4
5
6
7
8
9
10
11
12
    var customer = function () {
     var name ="Contoso";
     return {
          getName: function () {
                return name;
          },
          setName: function (newName) {
                name = newName;
          }
     };
}();
alert (customer.name);

这几乎是一个经典的JS模块模式 - 一个立即调用的函数表达式(IIFE),它返回一个对象,但也允许变量隐私。

我说几乎是因为模块模式通常看起来像这样。

1
2
3
var customer = (function () {
  //
})();

以下行将字符串作为局部变量范围并将其应用于name。由于其范围,它不能在IIFE之外访问。

1
var name ="Contoso";

因为函数立即被调用,所以返回此对象并将其应用于customer。一种方法返回name的值,另一种方法更新它。

1
2
3
4
return {
  getName: function () { return name; },
  setName: function (newName) { name = newName; }
};

但是,因为name对于IIFE(模块)是"私有的",所以customer.name返回undefined

要获取名称,请在返回的对象customer.getName()上使用该方法。

要设置新名称,请使用其他方法customer.setName('Bob')

DEMO

这两个方法都可以访问私有变量name,因为一个非常重要的概念被称为函数闭包,函数可以挂起("关闭")它的外部词法环境 - 在这种情况下很有用,以及事件监听器之类的东西。


变量customer未定义,因为它超出了函数的范围,在alert(customer.name);


当调用customer.name时,javascript发现customer被评估为:

1
2
3
4
5
6
7
8
9
10
function () {
 var name ="Contoso";
 return {
      getName: function () {
            return name;
      },
      setName: function (newName) {
            name = newName;
      }
 };

此函数中的变量name属于函数的内存或本地范围,并且在函数外部的任何位置都不可用。 name被声明为var名称而不是this.name,因此它不能通过该函数可用,只能用于函数。

所以在函数内部,我们可以说name = blah,但是超出了我们无法实现的功能。我们必须在函数内调用一个函数来访问它。这就是我们的getNamesetName。它们位于表示customer的函数内,因此可以访问局部变量name

我们可以在函数中使用this.name声明name,或者只是改变我们尝试访问customer.name的方式,如下所示:

1
alert( customer.getName() );