Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于JavaScript的变量提升 #86

Closed
Wscats opened this issue Mar 29, 2017 · 0 comments
Closed

关于JavaScript的变量提升 #86

Wscats opened this issue Mar 29, 2017 · 0 comments
Labels

Comments

@Wscats
Copy link
Owner

Wscats commented Mar 29, 2017

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant