Javascript 是否可以在 return 中声明函数?

Javascript Is it possible to declare functions in a return?

根据这篇文章(https://www.intertech.com/Blog/encapsulation-in-javascript/)下面的代码是JS封装的一个例子。它所做的基本上是限制修改变量 fullName 的可能性,因此只有当新的 fullName 没有数字时才可以更改。

  var person = (function () {

  var fullName = "Jason Shapiro";
  var reg = new RegExp(/\d+/);

  return {
    setFullName : function (newValue) {
      if( reg.test(newValue) ) {
        alert("Invalid Name");
      }
      else {
        fullName = newValue;
      }
    },
    getFullName : function () {
     return fullName; 
    }
  }; // end of the return
}());

alert(person.getFullName());  // Jim White is printed again.

person.setFullName( 42 ); // Invalid Name; the name is not changed

这一切对我来说似乎都是合乎逻辑的,但我无法得到的是,如果这些函数在 return 块中,他如何调用 getFullName 或 setFullName。

person 变量中,我们有一个 IIFE(立即调用的函数表达式),当解释器到达这一行时,它会立即执行。而这个函数 returns 是一个对象,所以最后 person 变量也是一个对象,正如我们所知,对象也可以包含函数,我们可以很容易地从这个对象调用函数,如下所示:

person.getFullName();
person.setFullName(42);

因为对象 person 正在被称为 自调用函数 的东西初始化:

(function () {
    // body of the function
}());

The anonymous function above will be invoked right after it has been defined. The benefit of self-invoking functions is that they enable us to execute code once without cluttering the global namespace (without declaring any globals). Reference

因此,您的对象在那一刻正在使用返回值进行初始化。

在你的情况下,有:

{
    setFullName: function(newValue) {
      if (reg.test(newValue)) {
        alert("Invalid Name");
      } else {
        fullName = newValue;
      }
    },
    getFullName: function() {
      return fullName;
    }
};

因此,对象 person 将使用这些函数进行初始化,因此您将能够调用 getFullNamesetFullName

我认为您在代码中没有注意到它的形式:声明一个函数并立即 运行。 person中存储的值不是一个函数,而是一个包含两个函数的对象。

function () { ... } 是一个函数。

(function () { ... )()) 是该函数的 return 值。

这个例子没什么好奇怪的;我们只需要将其分解即可。

  1. 正在声明一个名为 person 的变量。

  2. 人是什么物体?好吧,这是在零参数上调用匿名函数的结果。

  3. 当那个匿名函数被调用时,它returns一个对象。

  4. 函数返回的对象有两个属性,setFullNamegetFullName

  5. 函数返回的对象是变量person的值。因此 person.getFullNameperson.setFullName 都是有效的表达式。

我认为混淆点可能是您认为 getFullNamesetFullName 的范围仅限于 return 表达式内的代码。但是,JavaScript 是一种非常动态的语言。可以随时向对象添加和删除属性。它是在 运行 时间,而不是编译时间,JavaScript 解释器检查属性是否存在。