-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
BLOG博客博客
Description
这里讨论的是ES6之前的语法问题,自ES6以来,由于let、const声明的作用,作用域有所不同
JS代码在执行的时候,会先把变量申明提到最前面,也就是 js 会先把所有变量先申明好后再进行赋值等操作,并不是一边申明一边赋值。
变量提升
例1
var a=1;
var b=1;
实际是这样解析的:
var a;
var b;
a=1;
b=1;
例2
function foo() {
var a=1;
console.log(a);
console.log(b);
var b=1;
}
// print => 1
// print => undefined
foo();
实际:
function foo(){
var a;
var b;
a=1;
console.log(a);
console.log(b);
b=1;
}
例3
function foo() {
console.log(a);
a = 1;
var a = 2;
console.log(a);
}
// print => undefined
// print => 2;
foo();
这个有点复杂,有些人可能会认为,前面 a=1
会不会就是声明了一个全局变量 a
, 后面再声明局部变量,可以写个代码验证一下:
可以看到,如果没有后面的 var a=2;
前面 a=1
就是声明一个全局变量了。
所以前面的例子实际是这样的:
function foo() {
var a;
console.log(a);
a = 1;
a = 2;
console.log(a);
}
函数提升
函数声明和变量相同,也会在块的顶部先申明
例1
function foo() {
console.log(bar);
function bar(){}
}
// print => bar(){}
foo();
实际的样子:
function foo() {
function bar(){}
console.log(bar);
}
变量声明和函数声明同时存在
变量声明和函数声明同时存在时,遵循变量声明优先于函数声明的原则
function foo() {
console.log(a);
var a=1;
console.log(a);
function a() {}
console.log(a)
}
实际:
function foo() {
var a;
function a(){}
console.log(a);
a=1;
console.log(a);
console.log(a);
}
总结
总之,在相同作用域内,不管变量/函数写在什么位置,所有变量/函数都会被整体提升到作用域顶部,且函数申明是整体都在变量声明后面的。
当然了,如今这个都用 let
跟 const
的时代,里面有些规则是不适用的,因为浏览器压根不允许里面的一些操作。
let/const 大法好远离 var 保平安 😄
Ref
Metadata
Metadata
Assignees
Labels
BLOG博客博客