JavaScript——作用域

在JavaScript中有函数作用域、全局作用域以及块作用域

1、函数作用域:该作用域中的变量只生存在函数代码块中,但是如果使用隐式声明变量,该变量会成为全局变量,作用域为全局作用域(查看文章中的LHS查询机制就可以明白为什么会变成全局作用域

2、全局作用域:在代码中隐式声明的变量都会成为全局变量(非严格模式下),可以用window.变量来获取该全局变量

3、块作用域:有人认为JS中没有块作用域(因为在if、for等代码块中声明的变量都是可以在外部进行访问的),其实不然,JS中的with关键字(不建议使用,详情请参考这篇文章中的词法作用域)所创建出来的作用域只能在with声明中而非外部作用域中有效;在JS的ES3规范中规定的try/cathy中的cathy分句会声明块级作用域,在里面所声明的变量只能在cathy内使用;在ES6规范中引入了let关键字,该关键字会将变量绑定在所属的块级作用域

    关于作用域中的坑

    for循环

for(var i=0;i<10;i++){
    setTimeout(function(){
        console.log(i); //10
    },100)
}

上面代码会打印什么?0-9?错了,打印的结果是10个10,因为在定时器开始工作打印时,循环早就结束了,而循环的10个 i 变量使用var声明,都属于同一个作用域,在下一次循环的时候,i 会把前面一个 i 覆盖了,导致最后输出的 i 值为最后一次循环的 i 值;

如何让代码最后输出想要的0-9?最简单的就是把变量 i 用let声明就可以解决了,因为使用let声明的每个变量都有自己会块级作用域,相互之间不受影响,所以后面循环的 i 不会覆盖前面的 i ;

for(let i=0;i<10;i++){
    setTimeout(function(){
        console.log(i); //0-9
    },100)
}
    代码块(if关键字创建的代码块也一样)
console.log(test);  //undefined
console.log(a);     //undefined
{
    function test(){
        console.log("1231");
    }
    var a=100;
}
这个涉及到变量提升以及函数提升(提升就是代码在执行前会先查找变量声明以及函数声明,并把它们放在代码块的前面最先解析),因为 { }不属于块级作用域,所以变量提升时,把变量声明放在了外面,所以打印时为undefined,没有不会报错,但是并不能把函数的内容放在 { } 外面,所以函数text也打印了undefined,没有报错,如果把两个打印放在代码块的后面,就可以正常打印了
{
    function test(){
        console.log("1231");
    }
    var a=100;
}
console.log(test);  //[Function: test]
console.log(a);     //100

  结束分号与IIFE(立即执行函数)

    在JS中,大多数人的习惯都忽略一行程序结束的尾巴( ; ),但是有时候却会产生意想不到的bug

var aa=100
(
    function (){
        console.log(aa);
        
    }()
)
上面的代码,你会得到什么?得到的是一个错误(100 is not a function),在第一行的末尾没有加上分号,导致编译错误

猜你喜欢

转载自blog.csdn.net/yuhui01/article/details/81006645