首页 > 解决方案 > 命名函数表达式和函数声明有什么区别?

问题描述

  1. var a = 函数 b() {
        b = 123;
        console.log(b === window.a) // 真
        console.log(b) // 函数 b() { ... }
    }
  2. 函数 a() {
       a = 3;
       console.log(a) // 3
    }

为什么变量b不可变,它是什么?

标签: javascriptfunctionvariablesscope

解决方案


Javascript 中有两种类型的局部变量。这些是

  • 声明的局部变量:当您使用关键字之一(例如var,、、 )声明局部变量时constlet这些变量被确定为已声明。在非严格模式下,您的变量声明回退到var.
  • 人工局部变量:当您使用函数声明语法声明一个函数时,实际上是用函数的名称声明了一个人工局部变量。例如,function foo() {}定义一个名为foo.

JavaScript 在变量提升方面以不同的方式处理这两种类型的局部变量。声明的本地人需要到达要引用的声明(或他们的第一次使用)。另一方面,人工局部变量被提升到初始作用域状态,因此它从作用域开始就可以使用。

您可以考虑以下代码:

bar();      // prints 'bar' on the console
foo();      // error: 'undefined' is not callable

const foo = function () {
  console.log('foo');
}

function bar() {
  console.log('bar')
}

bar();      // prints 'bar' on the console
foo();      // prints 'foo' on the console

在您的示例中,您的a = 3语句在外部范围内声明了局部变量,覆盖了声明为函数声明副作用的旧人工局部变量。由于您使用的是非严格模式,因此很难看出差异,但是,您可能会这样考虑您的实现:

var a_dec = function b_art () {
  b_dec = 123;
  console.log(b_art === window.a_dec);
  console.log(b_art);
}

function a_art () {
  a_dec = 3;
  console.log(a_dec);

  // when you run this, b_art is not reachable with a_dec anymore
}

这是一个实现细节。在这里,声明函数的人工变量优先于声明的局部变量。是第a一次声明为声明变量,所以按原样计算。与人工变量相比,作为声明变量的问题使其可变。


推荐阅读