探究try catch的局部作用域问题

es3推出的try catch想必大家都不陌生,这是一个标准的捕获异常的方法。通常,遇到异常,浏览器会停止执行js并抛出异常。如果出现异常的代码在try catch内,浏览器不会中断js线程,而是会执行catch内的代码,触发catch函数并将异常作为参数传递给函数。

这篇文章暂且只讨论try catch创建的作用域,不专门介绍用法。try catch具体用法参考 try catch MDN

在es6的let和const推出之前,除了已经废弃的with,以及这里讨论的 try catch,js并没有块作用域的概念,只有全局作用域和函数作用域。

不过,catch创建的块作用域也不是通常的块作用域。

下面是个例子

function foo(){
            e='aaa'
            try{
                throw new Error('this is an error')
            }catch(e){
                console.log(e)
            }
            console.log(e)
            console.log(window.e)
        }
        foo()

结果是

探究try catch的局部作用域问题_第1张图片

在函数里面先默认声明了一个全局变量,变成了window的一个属性。

如果在catch里面声明一个变量e呢?

如果用var声明变量e,那么按照块作用域的特性,不会影响外部的变量e。然而,结果并不是这样

function foo(){
            e='aaa'
            try{
                throw new Error('this is an error')
            }catch(e){
                var e;
                console.log(e)
            }
            console.log(e)
            console.log(window.e)
        }
        foo()

探究try catch的局部作用域问题_第2张图片

可以看到,外部的e='aaa'并没有给window绑定上e属性,对比上一次的代码,很容易就能得出结论:

catch里面对e的声明提升到了foo顶部。

所以,catch的作用域,其实并不是常见的块作用域,并不能绑定自己的内部声明的变量。

接下来,在catch内部更改e的值。

function foo(){
            e='aaa'
            try{
                throw new Error('this is an error')
            }catch(e){
                var e;
                console.log(e)
                e='this is not an error';
                console.log(e)
            }
            console.log(e)
            console.log(window.e)
        }
        foo()

探究try catch的局部作用域问题_第3张图片

如下。catch内部的e已经更改了,不过外部的e还是原始值。这也说明catch的确创建了一个作用域,catch的作用域的内部变量e的值并没有影响到外部作用域的e的值。

再来试试对其他属性的影响

function foo(){
            e='aaa'
            a='a'
            try{
                throw new Error('this is an error')
            }catch(e){
                var e,a='b';
                console.log(e)
                e='this is not an error';
                console.log(e)
            }
            console.log(e)
            console.log(window.e)
            console.log(a)
        }
        foo()

探究try catch的局部作用域问题_第4张图片

所以,catch的作用域并不能影响其他属性。

由此,可以推测出:

catch创建的块作用域,只对catch的参数有效。对于在内部声明的变量,catch并没有创建一个新的作用域,只是一个普通的代码块。

 

你可能感兴趣的:(原生js)