JavaScript作用域特例(只有函数作用域无块级作用域)

//备忘下 以便下次回看 研究

function test(o) {
    var i = 0; // i在整个函数体内均是有定义的
    if (typeof o == "object") {
        var j = 0; // j在函数体内是有定义的,不仅仅是在这个代码段内
        for (var k = 0; k < 10; k++) { // k在函数体内是有定义的,不仅仅是在循环内
            console.log(k); // 输出数字0~9
        }
        console.log(k); // k已经定义了,输出10
    }
    console.log(j); // j已经定义了,但可能没有初始化
}
//JS中不像java有块级作用域{},只有函数作用域,所以在同一个函数内的变量都是同一个作用域。所以以上例子能够访问到k和j
因为他们都是在同一个函数内,如果不考虑兼容性用ES6 中的let声明,此时JS会有块级作用域 访问k会报k is not undefined错误导致程序崩溃
而下面这个例子a之所以报a is not undefined错误,因为他们是两个不同函数,即在各自的函数作用域,无法访问
(function(){
    (function(){
     var a= 5;
}())
alert(a); //这里却会报错a is not undefined
}())

JavaScript 的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味着变量在声明之前甚至已经可用。JavaScript 的这个特性被非正式地称为声明提前(hoisting),即 JavaScript 函数里声明的所有变量(但不涉及赋值)都被「提前」至函数体的顶部,看一下如下代码:

var scope = "global";
function f() {
    console.log(scope);  // 输出"undefined",而不是"global"
    var scope = "local"; // 变量在这里赋初始值,但变量本身在函数体内任何地方均是有定义的
    console.log(scope);  // 输出"local"
}

你可能会误以为函数中的第一行会输出 "global",因为代码还没有执行到 var 语句声明局部变量的地方。其实不然,由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名全局变量。尽管如此,只有在程序执行到 var 语句的时候,局部变量才会被真正赋值。因此,上述过程等价于:将函数内的变量声明“提前”至函数体顶部,同时变量初始化留在原来的位置:

function f() {
    var scope;          // 在函数顶部声明了局部变量
    console.log(scope); // 变量存在,但其值是"undefined"
    scope = "local";    // 这里将其初始化并赋值
    console.log(scope); // 这里它具有了我们所期望的值
}
var 声明的是函数级别的局部变量,并且 var 有声明提升的特性,不论var写在一个函数的哪里,都会自动提升到这个函数内的最前面。如:

JavaScript code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function  myname() {
     for  (.............) {
         if  (.....) {
             var  n = 123;
         }
     }
}
在js解析时就会变成下面的形式
function  myname() {
     var  n;
     for  (.............) {
         if  (.....) {
             n = 123;
         }
     }
}


let 声明的变量才是语句块级别的局部变量。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值