你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。
在JavaScript中,var
关键字用于声明变量。与 let
和 const
不同,var
声明的变量具有函数作用域或全局作用域(如果声明在函数外部)。关于 var
声明的一个重要特性是声明提升(Hoisting)。
声明提升
声明提升意味着无论 var
变量在函数的哪个位置声明,它都会被视为在函数顶部声明。但是,需要注意的是,只有变量的声明会被提升,而变量的初始化(即赋值)不会被提升。这意味着在变量被实际初始化之前,对于 var
来说,它会被视为 undefined
。
代码示例
function testVarHoisting() {
console.log(a);
var a = 2;
}
testVarHoisting(); // undefined
- 1
- 2
- 3
- 4
- 5
- 6
注意事项
- 声明提升只影响声明本身,不影响初始化。
- 使用
var
可能会导致意外的行为,特别是当在大型或复杂的代码库中时。因此,推荐使用let
和const
来声明变量,因为它们提供了块级作用域,减少了变量泄露到全局作用域或意外覆盖的风险。 - 在严格模式(strict mode)下,未声明的变量会导致错误,这有助于捕获潜在的错误。然而,
var
声明的变量仍然可以被提升。
练习题 1
function complexFunction() {
console.log(a); // 输出什么?
if (false) {
var a = 10;
}
console.log(a); // 输出什么?
var a = "Hello";
console.log(a); // 输出什么?
}
complexFunction();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
答案:undefined,undefined,Hello 【if语句不影响var的变量提升,无论真假】
练习题 2
function complexFunction() {
console.log(a); // 输出什么?
if (true) {
var a = 10;
}
console.log(a); // 输出什么?
var a = "Hello";
console.log(a); // 输出什么?
}
complexFunction();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
答案:undefined,10,Hello
练习题 3
console.log(x); // 输出什么?
var x = 2;
function f() {
console.log(x); // 输出什么?
var x = 3;
console.log(x); // 输出什么?
}
f();
console.log(x); // 输出什么?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
答案:undefined,undefined,3,2
练习题 4
"use strict"; // 严格模式
console.log(x); // 输出什么?
var x = 2;
function f() {
console.log(x); // 输出什么?
var x = 3;
console.log(x); // 输出什么?
}
f();
console.log(x); // 输出什么?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
答案:undefined,undefined,3,2 【严格模式不影响var的声明提升】
练习题 4
console.log(x); // 输出什么?
var x = 2;
function f() {
x = 3; // 输出什么?
console.log(x); // 输出什么?
var x = 4;
console.log(x); // 输出什么?
}
f();
console.log(x); // 输出什么?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
答案:undefined,3,4,2【函数作用域的同名变量不会给外层变量赋值】
练习题 5
function test(x) {
var x = "local";
console.log(x); // 输出什么?
}
test(10);
- 1
- 2
- 3
- 4
- 5
- 6
答案:“local”
function test(x) {
console.log(x); // 输出什么?
var x = "local";
console.log(x); // 输出什么?
}
test(10);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
答案:10,“local”【函数参数的优先级高于变量提升】
练习题 6
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i); // 输出什么?
}, 1000);
}
- 1
- 2
- 3
- 4
- 5
答案:3,3,3 【var为全局变量,定时器回调在循环结束后执行】
练习题 7
var name = "World!";
(function() {
if (typeof name === "undefined") {
var name = "Jack";
console.log("Goodbye " + name)
} else {
console.log("Hello "+ name);
}
})();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
答案:Goodbye Jack 【逻辑同习题1,if语句不影响var的变量提升,无论真假】
练习题 8
var msg = "hello";
for (var i = 0; i < 10; i++) {
var msg = 'hello' + i * 2 + i;
}
console.log(msg);
- 1
- 2
- 3
- 4
- 5
答案:“hello189”【for循环内部的变量会覆盖外层的同名变量】
总结
如果上面的习题你都做对了,那你对var
变量提升问题的理解是比较深刻的,给你点赞????!
从以上习题中可以看出 var
声明变量存在很多"诡异"情况,特别是赋值前可以访问变量和重复赋值导致很多问题,你有时要看很久才能想明白执行顺序,这极不利于代码的维护,这也是提倡用 let
和 const
代替 var
的原因。项目开发中,同学们也应该尽量使用let
和const
代替var
。
好了,分享结束,谢谢点赞,下期再见。