javascript - 当变量等于函数时,这意味着什么?

标签 javascript function coding-style convention

<分区>

Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}

在 JavaScript 中,将变量定义为函数的目的是什么?我以前见过这个约定,但并不完全理解它。

例如,在脚本的某个时刻,一个函数被这样调用:

whatever();

但我希望看到一个名为 whatever 的函数,如下所示:

function whatever(){

}

相反,我会看到一个名为 whatever 的变量,它被定义为一个函数,如下所示:

var whatever = function(){

}

这样做的目的是什么?为什么要这样做而不只是命名函数?

最佳答案

注意:请参阅答案末尾的更新, block 内的声明变得有效(但如果您不使用严格模式,则相当复杂)。


这是一个原因:

var whatever;

if (some_condition) {
    whatever = function() {
        // Do something
    };
}
else {
    whatever = function() {
        // Do something else
    };
}
whatever();

您可能会在必须处理实现差异的库的初始化中看到类似的代码(例如 Web 浏览器之间的差异,a'la IE 的 attachEvent 与标准 addEventListener)。你不能用函数声明做同样的事情:

if (some_condition) {
    function whatever() {    // <=== DON'T DO THIS
        // Do something
    }
}
else {
    function whatever() {    // <=== IT'S INVALID
        // Do something else
    }
}
whatever();

...它们没有在控制结构中指定,所以 JavaScript 引擎可以做他们想做的事,不同的引擎做不同的事情。 (编辑:再一次,请参阅下面的注释,它们现在已指定。)

分别来说,两者之间有很大的区别

var whatever = function() {
    // ...
};

function whatever() {
    // ...
}

第一个是函数表达式,当代码在逐步执行上下文(例如,它所在的函数,或逐步-逐步执行全局代码)。它还会生成一个匿名 函数(引用它的变量有一个名称,但函数没有,这对 helping your tools to help you 有影响)。

第二个是函数声明,它在进入上下文时进行评估,执行任何分步代码之前。 (有些人称此为“提升”,因为源代码中更底层的事情比源代码中更高层的事情发生得更早。)该函数也被赋予了一个合适的名称。

所以考虑:

function foo() {
    doSomething();
    doSomethingElse();
    console.log("typeof bar = " + typeof bar); // Logs "function"

    function bar() {
    }
}

鉴于

function foo() {
    doSomething();
    doSomethingElse();
    console.log("typeof bar = " + typeof bar); // Logs "undefined"

    var bar = function() {
    };
}

在第一个示例中,通过声明,声明在doSomething 和其他分步代码运行之前 被处理。在第二个示例中,因为它是一个表达式,所以它作为逐步代码的一部分执行,因此函数没有在上面定义(变量在上面定义,因为 var is also "hoisted" )。

最后:目前,您不能在一般的客户端 Web 内容中执行此操作:

var bar = function foo() { // <=== Don't do this in client-side code for now
    // ...
};

应该能够做到这一点,它被称为命名函数表达式,它是一个为函数赋予适当名称的函数表达式。但是不同时期的各种 JavaScript 引擎都出错了,IE continued to get very wrong indeed until very recently .


ES2015+更新

从 ES2015(又名“ES6”)开始, block 内的函数声明已添加到规范中。

严格模式

在严格模式下,新指定的行为简单易懂:它们被限制在它们出现的 block 内,并被提升到 block 的顶部。

所以这样:

"use strict";
if (Math.random() < 0.5) {
  foo();
  function foo() {
    console.log("low");
  }
} else {
  foo();
  function foo() {
    console.log("high");
  }
}
console.log(typeof foo); // undefined

(请注意对函数的调用是如何高于 block 中的函数的。)

...本质上等同于:

"use strict";
if (Math.random() < 0.5) {
  let foo = function() {
    console.log("low");
  };
  foo();
} else {
  let foo = function() {
    console.log("high");
  };
  foo();
}
console.log(typeof foo); // undefined

宽松模式

松散模式行为要复杂得多,而且理论上它在网络浏览器中的 JavaScript 引擎和网络浏览器中的 JavaScript 引擎之间有所不同。我不会在这里深入。只是不要这样做。如果您坚持在 block 内声明函数,请使用严格模式,因为它们有意义并且在整个环境中保持一致。

关于javascript - 当变量等于函数时,这意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9467155/

相关文章:

php-cs-修复程序 : need more information on using fix --level option

scala - 排除行为的首选方式是什么

javascript - 使用数组作为输入参数实现斐波那契

java - 从字符串到整数函数

Mysql View 需要限制功能

C++:指向具有可变数量参数的函数的函数指针

php - 属性可以为 false、数组或 null 是否可以

javascript - 集成 Jest 和 Rewire

javascript - Windows.onload 范围问题

javascript - Ajax响应不带数据