变量的作用域问题

一、 什么是作用域
作用域,即 变量起作用的区域。
变量定义后,可以在哪个范围内使用该变量
二、两种作用域
     1.词法作用域、
     2.块级作用域
块级作用域:
用一个块(代码块)结构限制变量的访问区域。
即,块内的每一段代码都有各自的作用域,变量在声明它们的代码段之外是不可见的。
代表语言: C 语言( C系,如:Java、Object-C、C#)
 
案例
 
for(var i = 0; i < 10; i++) {
    console.log(i);
}
 
console.log(i);//10
 
三、词法作用域
     
概念:变量的作用范围, 在书写代码的时候就已经决定, 与运行时无关。
            函数在定义它们的作用域中运行,而不是在调用它们的作用域里运行
            JavaScript中只有函数才能形成作用域,因此也叫做函数作用域
案例:
 
// 1
function foo() {
    var num = 123;
    console.log(num);  // 
}
foo();
console.log(num); //
变量提升后:
function foo(){
     var num;
     num = 123;
     console.log(num); =>123
}
foo();
console.log(num);//先去当前作用域里面找,看有没有声明;因为是全局环境下,所以没有找到num,程序会报错

// 2
var scope = "global";
function foo() {
    console.log(scope); //
    var scope = "local";
    console.log(scope); //
}
foo();
变量提升后:
var scope;
    scope = "global";
function foo(){
     var scope;
     console.log(scope); =>先去当前作用域找变量的声明,如果没有则向上一级找,本例中,当前作用域中有声明,但是在该位置没有赋值,所以输出undefined
     scope = "local";
   console.log(scope); =>先去当前作用域找变量的声明,如果没有则向上一级找,有声明,并且有赋值,所以输出local
}
foo();
// 3
// 声明的变量都作为 window 全局对象的属性存在!
if("a" in window){
    var a = 10; =>因为这里并不是一个作用域,所以变量会向上提升至全局环境,
}
alert(a); // ? 
变量提升后
var a ;
if('a' in window){
     a = 10;
}
alert(a); =>10;
if(!"a" in window){
    var a = 10;
}

alert(a); // ?
 
// 4
var foo = 1;
function bar() {
    if(!foo) {
        var foo = 10;
    }
    alert(foo); //
}
bar();
 
变量提升后
var foo;
foo = 1;
function bar(){
   var foo;
   if(!foo){     =>foo声明未赋值,为undefined,隐式转换为false ,经过非运算符之后为true
      foo = 10;
    }
   console.log(foo); =>因为上面条件为真,程序进入判断语句中,foo为10;所以最后输出10
}
bar();
 
四、变量提升和函数提升(hoisting)
  • JavaScript的执行过程
JS运行的两个步骤:解析和执行
1 预解析(不是在执行代码)。 将所有的声明都加载到内存中,也就是:告诉解释器有什么东西了
2 一步一步的执行代码, 按照从上往下的顺序
  • 变量提升的是:变量的声明
  • 函数提升的是:整个函数
案例变式:
2 变式
if("b" in window) {
    var a = 10;
}
alert(a); // ? undefined
变量提升后
var a ;
if('b' in window){
     var a = 10;
}
console.log(a);
3 变式
if(true) {
    function f() { alert("true"); }
} else {
    function f() { alert("false"); }
}
f();// ? 不确定,会根据不同浏览器实现不同
 
4 变式
var f;
if(true) {
    f = function () { alert("true"); }
} else {
    f = function () { alert("false"); }
}
f();// true
 
原文地址:https://www.cnblogs.com/songdongdong/p/6241222.html