-
Notifications
You must be signed in to change notification settings - Fork 732
Closed
Labels
Description
var v='Hello World';
alert(v);
弹出“Hello World”
var v='Hello World';
(function(){
alert(v);
})()
也是弹出了“Hello World”
var v='Hello World';
(function(){
alert(v);
var v='I love you';
})()
弹出了“undefined”
这里面隐藏了一个陷阱,就是JavaScript中的变量提升
它相当于
var v='Hello World';
(function(){
var v;
alert(v);
v='I love you';
})()
变量提升,简单的理解,就是把变量提升提到函数的最顶的地方。需要说明的是,变量提升只是提升变量的声明,并不会把赋值也提升上来,没赋值的变量初始值是undefined。所以上面就出现了声明为undefined的var,因为赋值在后面声明提升在了前面。
function foo() {
if (false) {
var x = 1;
}
return;
var y = 1;
}
function foo() {
var x, y;
if (false) {
x = 1;
}
return;
y = 1;
}
还有一点注意的是因为 JavaScript 是函数级作用域,只有函数才会创建新的作用域,而不像其他语言有块级作用域,例如:块,就像 if 语句,在上面例子中,不管会不会进入 if代码块,函数声明都会提升到当前作用域的顶部,得到执行,在js中并不会创建一个新的作用域(在C语言等语言中却是一个新的作用域,上面这个例子,两个函数实际上是一样的)。
从这里我们应该体会到,当我们在写 JavaScript Code 的时候,我么需要把变量放在块级作用域的顶端,不然容易发生一些意想不到的错误。
注意:ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
还有一种就是函数提升
function myTest(){
foo();
function foo(){
alert("Hello World");
}
}
myTest();
弹出“Hello World”
这里函数提升成功
function myTest(){
foo();
var foo =function foo(){
alert("我来自 foo");
}
}
myTest();
报错:foo不是函数
函数提升失败
这种题目,也是涉及函数提升的
{
a = 1;
function a() { };
a = 2;
console.log(a); // 2
}
console.log(a); // 1
但是比上面会复杂一点,因为还涉及到块作用域,因为函数写在块作用域里面,由于函数提升,它即能访问局部作用域,也能访问全局作用域,所以此时会在全局作用域和块级作用域都产生一个变量 a
JavaScript 执行到函数所在的那一句把局部变量的内容扔给外面的那个变量
即相当如下的代码:
let outera;
{
let innera;
innera = function () { };
innera = 1;
// function a() { };
outera = innera; // JavaScript 执行到函数所在的那一句把局部变量的内容扔给外面的那个变量
innera = 2;
console.log(innera); // 2
}
console.log(outera); // 1
Metadata
Metadata
Assignees
Labels
Projects
Milestone
Relationships
Development
Select code repository
Activity