如果 JavaScript 中的 var 定义了两次,解释器应该采用哪个定义?
If a var in JavaScript is defined twice, which definition should the interpreter take?
我是 JavaScript 的新手,正在尝试理解提升和作用域的概念。
案例一
var name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
并且我在控制台中有以下输出
Auro 1
Auro 2
如果我没理解错hoisting
,JS引擎是先吊起一个变量的声明,然后自动给它赋值undefined
。只有当它遇到赋值(=
)运算符时,它才真正给它赋值。
如果我上面的理解是正确的,那么第一次调用logName
函数时,变量name
应该打印undefined,但它打印的是值。
案例二
var name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
name = "Baner";
控制台输出:
Baner 1
Auro 2
这让我更加困惑。这里函数 logName
的第一次调用选择了后来对变量的赋值并打印了 Baner
,然而,第二次调用选择了之前的赋值,即 Auro
.
这是怎么回事?我错过了什么?
除了我可以说的其他答案之外,只是不使用 var
而是使用 ES6 let
或 const
而 'surprising behaviour' 将会消失。
let name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
name = "Baner";
在全局范围内,name
指的是 window.name
,即 window 的 name
属性 - 在您给出的示例中是 sif1
和 sif2
(可能是 "Snippet IFrame 1/2")。
因为 window.name
已经存在,所以 var name;
在全局范围内什么都不做。变量已定义。
直到你覆盖它 - 请注意你再次设置全局 window.name
属性。而且,根据浏览器设置,这可以在页面重新加载时持续存在(因为您正在命名整个 window
)。这解释了为什么您会看到值 "stick".
指定输出中没有 none 匹配,因为最初 name
的值等于 window.name,所以最初 name
变量的值将相等到 winow.name
并在覆盖它后得到新值
让我们了解这一切是如何运作的
你可以这样理解代码执行有两个阶段
- 创作阶段
- 执行阶段
创建阶段:-创建阶段函数原样吊顶,变量吊顶但没有分配给它的值(或者你可以说它的值是未定义的)
执行阶段:- 在执行上下文期间,它会在到达发生赋值的行时为变量赋值
var name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
name = "Baner";
我是 JavaScript 的新手,正在尝试理解提升和作用域的概念。
案例一
var name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
并且我在控制台中有以下输出
Auro 1
Auro 2
如果我没理解错hoisting
,JS引擎是先吊起一个变量的声明,然后自动给它赋值undefined
。只有当它遇到赋值(=
)运算符时,它才真正给它赋值。
如果我上面的理解是正确的,那么第一次调用logName
函数时,变量name
应该打印undefined,但它打印的是值。
案例二
var name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
name = "Baner";
控制台输出:
Baner 1
Auro 2
这让我更加困惑。这里函数 logName
的第一次调用选择了后来对变量的赋值并打印了 Baner
,然而,第二次调用选择了之前的赋值,即 Auro
.
这是怎么回事?我错过了什么?
除了我可以说的其他答案之外,只是不使用 var
而是使用 ES6 let
或 const
而 'surprising behaviour' 将会消失。
let name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
name = "Baner";
在全局范围内,name
指的是 window.name
,即 window 的 name
属性 - 在您给出的示例中是 sif1
和 sif2
(可能是 "Snippet IFrame 1/2")。
因为 window.name
已经存在,所以 var name;
在全局范围内什么都不做。变量已定义。
直到你覆盖它 - 请注意你再次设置全局 window.name
属性。而且,根据浏览器设置,这可以在页面重新加载时持续存在(因为您正在命名整个 window
)。这解释了为什么您会看到值 "stick".
指定输出中没有 none 匹配,因为最初 name
的值等于 window.name,所以最初 name
变量的值将相等到 winow.name
并在覆盖它后得到新值
让我们了解这一切是如何运作的
你可以这样理解代码执行有两个阶段
- 创作阶段
- 执行阶段
创建阶段:-创建阶段函数原样吊顶,变量吊顶但没有分配给它的值(或者你可以说它的值是未定义的)
执行阶段:- 在执行上下文期间,它会在到达发生赋值的行时为变量赋值
var name;
function logName(num) {
console.log(name, num);
}
logName(1);
name = "Auro";
logName(2);
name = "Baner";