关于作用域

   JS会在执行之前编译,并采取相应优化例如JIT优化;编译分为分词、语法分析、代码生成过程。

   而作用域是关于变量(或是标识符)去何处查询以及如何查询的一套规则。分为RHS、LHS查询,RHS找到对应位置且要返回值,LHS查询会找到对应的空间。LHS在非严格模式下在无法找到的情况下在全局对象中建立变量且返回,严格模式下会出错“Reference Error”。简而言之,reference error是作用域判别失败,typeerror是作用域判别成功但是执行操作不当。

   作用域包括函数作用域、块级作用域。利用函数作用域可以用来隐藏信息,避免命名冲突(可以为一个编译单元使用一个统一的命名空间,可以使用模块的方式)。但是用函数来封装的问题是什么呢?第一,它会污染作用域;其次,还要显示的调用。那就可以使用IIFE了。

   1、函数表达式与函数声明的区别,主要是语句开头的词法单元是不是"function"。若是表达式则可以用()(),(())不同的调用模式了。

  2、函数声明是不可以匿名的,函数表达式可以。

   匿名函数问题: 1、在栈追踪的调试上比较困难;2、在递归运算时不得不使用arguments.callee这种过时的技术。

  IIFE作用:1、可以避免污染作用域以及不用显示调用;

                2、可以使用所谓的UMD模式。见下面:

var a = "demo string";
(function (def) {
     def(window);
}(function (global) {
     console.log(global.a);   //"demo string";  
}));

 

第二部分

      块级作用域

     1、with. 它会将with限定的obj添加到其后代码块的标识符的作用域的前端。

     2、try/catch的catch分句(es3中就有)。用于在不支持let语句条件下人为建立一个块级作用域。

//let 语句形式
let a = 3;
console.log(a);
//catch的实现
{
     try {
           throw 3; 
     } catch (a) {
            console.log(a);
     }
}

   google支持一个叫做Traceur的项目,将ES6的代码向转为可以向下兼容的形式。

      3、let.let不会提升变量,在垃圾收集、闭包(多是循环等)中有重要的作用。

      4、const。这个是建立块级的常量。

 {
     const a = "inner";
     console.log(a);   //"inner" 
}
console.log(a);       //reference error;

 

posted @ 2016-10-16 16:27  月下夜行  阅读(155)  评论(0编辑  收藏  举报