var a = function b() { b = 123; console.log(b === window.a) // true console.log(b) // function b() { ... } }
function a() { a = 3; console.log(a) // 3 }
为什么变量b
不可更改,它是什么?
var a = function b() { b = 123; console.log(b === window.a) // true console.log(b) // function b() { ... } }
function a() { a = 3; console.log(a) // 3 }
为什么变量b
不可更改,它是什么?
var
,const
,let
)声明本地变量时,这些变量被确定为已声明。在非严格模式下,您的变量声明会回退到var
。
- 人工本地变量:当您使用函数声明语法声明函数时,实际上声明了一个名为函数名称的人工本地变量。例如,function foo() {}
定义了一个名为foo
的人工本地变量。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
首次被声明为已声明变量,因此它被视为它本身。成为已声明变量的问题使它可变,与人工变量相反。
use strict
,会得到Uncaught TypeError: Assignment to constant variable.
(但这与const
不同)。 - CertainPerformance