Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

try-catch语句的“伪块作用域”

  在ES6之前是没有块作用域的。但是在try语句的catch部分有个奇怪的情况。catch是带一个参数的,它并没有使用函数作用域,却不会影响所在作用域中的同名变量。但是在catch的语句块中声明的变量却又完全遵循普通语句块的规则,只有catch的参变量特殊。
(function(){
  e="default";
  try{
    throw "test";
  }catch(e){
    var e,x=123;
    console.log(e); //test
    console.log(delete e); //false
    e=456;
    console.log(e); //456
  };
  console.log(x); //123
  console.log(e); //default
  console.log(window.e); //undefined
})();

  这个测试代码测试了很多东西。函数中第一行给e赋值时这个e是局部还是全局的?由于var在catch的语句块中,如果catch语句块是个块作用域,那么e就是全局的。但是函数中的最后一行输出的是undefined,也就是说它并不是全局的,因此可以推出catch后面的大括号是普通语句块的性质。这个语句块中的var语句影响的是所在的作用域而已,所以e和x都被定义到了所在的作用域上。
  catch的参变量是一个错误信息,我们在try语句中throw过去的那个错误信息就可以在catch中得到。所以在catch语句块中输出第一个e的结果是try语句块中throw过来的test字符串。接着,我们尝试删除e这个变量,发现失败了。这说明e是一个栈变量或逻辑栈变量,JavaScript在实现这个catch后面的语句块时确实把它视为函数作用域来处理,只是对里面的var之类的特殊语句做了特殊处理。
  我们在catch作用域中对e进行了读写,这些基本操作都是允许的。并且操作catch语句块中的e对try系列语句所在的作用域并没有影响,这个结论以在函数倒数第二行输出最初赋予的default字符串中得到。所以这个e的性质可以视为唯一一个把catch语句块当做块作用域的变量,它的生存周期只在这个语句块中。或者说是catch语句块的局部变量。
  因此,我称这个catch的语句块为“伪块作用域”!
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^