javascript - javascript中模块的两个声明有什么区别?

标签 javascript module iife

JavaScript 中模块的两个声明有何不同? 一个在函数周围有括号,而另一个没有?

一篇文章说

Notice the () around the anonymous function. This is required by the language, since statements that begin with the token function are always considered to be function declarations. Including () creates a function expression instead.

检查时两者似乎做同样的事情。

var person = (function () {
    // Private
    var name = "Robert";
    return {
        getName: function() {
            return name;
        },
        setName: function(newName) {
            name = newName;
        }
    };
}());

var person = function () {
    // Private
    var name = "Robert";
    return {
        getName: function() {
            return name;
        },
        setName: function(newName) {
            name = newName;
        }
    };
}();

最佳答案

函数在 JavaScript 中有两种类型 - 声明和表达式。

这是两者的区别:

  1. 函数声明被提升。这意味着您可以在函数出现在程序中之前调用该函数,因为 JavaScript 中的声明被提升
  2. 可以立即调用函数表达式。函数声明不能​​。这是因为表达式表示(或返回一个值)。函数表达式表示一个函数。

一个函数声明的例子:

foo("bar");

function foo(bar) {
    alert("foo" + bar);
}

上面的程序可以运行,因为 foo 是一个函数声明。

foo("bar"); // throws an error, foo is undefined - not a function

var foo = function (bar) {
    alert("foo" + bar);
};

上面的程序将无法运行,因为 foo 被声明为 undefined,被提升,然后被赋予一个函数表达式的值。因此它在被调用时是 undefined

一个函数表达式的例子:

(function (bar) {
    alert("foo" + bar);
}("bar"));

上面的函数将被立即调用,因为它是一个函数表达式。

function (bar) {
    alert("foo" + bar);
}("bar"); // throws an error, can't call undefined

上面的函数不会被立即调用,因为它是一个函数声明。请记住,声明不表达(或返回值)。所以这就像尝试将 undefined 作为函数调用。

函数如何变成表达式?

如果在需要表达式的上下文中使用函数,则将其视为表达式。否则,它被视为声明。

在以下情况下需要表达式:

  1. 您正在为变量赋值(即 identifier = expression)。
  2. 括号内(即 ( expression ))。
  3. 作为运算符的操作数(即运算符表达式)。

因此以下都是函数表达式:

var foo = function () {};
(function () {});
~function () {};

其他一切都是函数声明。简而言之,如果您的函数前面没有任何内容,它就是一个声明。

查看此代码:https://github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94

下面的函数 isExpression 用于测试一些任意的 JavaScript 代码是否是一个表达式:

function isExpression(code) {
    if (/^\s*function\s/.test(code)) return false;

    try {
        Function("return " + code);
        return true;
    } catch (error) {
        return false;
    }
}

希望这能消除您心中的任何疑虑。

简而言之:

  1. 一个函数表达式表达或返回一个值(在本例中是一个函数)。因此它可以被立即调用,但不能在它出现在程序中之前被调用。
  2. 函数声明被提升。因此它可以在它出现在程序中之前被调用。但是,由于它不表示任何值,因此无法立即调用。

关于javascript - javascript中模块的两个声明有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15023560/

相关文章:

module - 如何在NodeJS中通过字符串 "foo"访问函数 "foo"?

python - 如何找到python模块的功能?

iife - 有人可以解释一下这个 javascript 片段吗?

JavaScript 和 .js 文件结尾,对外部引用页面的严格要求?

javascript - 防止嵌套元素触发父元素的事件

Ruby 在模型中包含模块的单一方法

javascript - 如何在不同的文件中为 Angular JS 定义常量

javascript - javascript 中的 IIFE 内存效率更高吗?

javascript - 无法在 jqGrid 中格式化日期

javascript - Three.js:缩放几何后错误的 BoundingBox