【问题标题】:JavaScript Hoisting: Function Can Refer to Another Function Declared Below It?JavaScript 提升:函数可以引用在它下面声明的另一个函数吗?
【发布时间】:2019-07-31 01:29:51
【问题描述】:

我有:

// Shouldn't we have the following hoisted?
// var multiply; (undefined)
// var add; (undefined)

var multiply = function(num) {
  return add(num) * 2;
};

var add = function(num) {
  return num + 1;
};

console.log(multiply(1)); // No error, somehow "multiply" calls "add"!

我认为 JavaScript 变量被提升到顶部,而不是它们被分配的值。不知何故,multiply 调用 add 不会返回错误,即使 add 声明在 multiply 之下。

【问题讨论】:

  • 我认为是这样,基于我对阅读此blog.bitsrc.io/… 的公认有缺陷的记忆,这可能会比您想知道的更多。我记得的基础知识包括每个函数都有自己的执行上下文,其中包括几个内部词法环境(其中一个特定于那些用var 声明的标识符)并且这些词法环境可以访问外部环境。另外,我认为 varfunction 声明会被提升,但 letconst 声明不会......
  • 解释很简单。 JS 让你的函数引用不存在的变量。因此,只有在调用函数之后才会出现错误的可能性。在调用时,如果引用的变量不存在,则会出现错误。作为测试,删除add() 函数,并更新multiply(),使其使用try/catch,其中try 尝试调用add()catchwindow.add = function() {...} 创建它。您会看到 ReferenceError 在第一次调用时被捕获,但后续调用成功。
  • ...像这样:jsfiddle.net/cpzj309w

标签: javascript function scope hoisting lexical


【解决方案1】:

你是正确的,声明被提升到顶部,而分配没有。

但是,从创建时开始,函数不会保留它们之外的任何变量的值。相反,当他们被调用时,他们会使用其中的任何内容。在这种情况下,add 在创建multiply 函数时是undefined,但在调用multiply 之前分配了一个函数,因此multiply 使用新分配的函数。

要更清楚地看到这一点,请考虑以下代码:

var multiply = function(num) {
    return add(num) * 2;
};

// Would be an error
// console.log(multiply(1));

var add = function(num) {
    return num + 1;
};

console.log(multiply(1)); // Prints 4

add = function(num) {
    return num + 2;
};

console.log(multiply(1)); // Prints 6

最后一个console.log 打印6,因为multiply 使用了add 中的新函数,而不是保留之前的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多