作用域
section 1
JS会在执行之前编译,并采取相应优化例如JIT优化;编译分为分词、语法分析、代码生成过程。
作用域是关于变量(或是标识符)去何处查询以及如何查询的一套规则。分为RHS、LHS查询、RHS找到对应位置且要返回值,LHS查询会找到对应的空间。LHS在非严格模式下在无法找到的情况下在全局对象中建立变量且返回,严格模式下会出错“Reference :Error”。简而言之,reference error是作用域判别失败,typeerror是作用域判别成功但是执行操作不当。
作用域包括函数作用域、块级作用域。利用函数作用域可以用来隐藏信息,避免命名冲突(可以为一个编译单元使用一个统一的命名空间,可以使用模块的方式)。但是用函数来封装的问题是什么呢?第一,它会污染作用域;其次,还要显示的调用。那就可以使用IIFE了。
- 函数表达式与函数声明的区别,主要是语句开头的词法单元是不是”function”。若是表达式则可以用()(),(())不同的调用模式了。
函数声明是不可以匿名的,函数表达式可以。
匿名函数问题:1、在栈追踪的调试上比较困难;2、在递归运算时不得不使用arguments.callee这种过时的技术。
IIFE作用:1、可以避免污染作用域以及不用显示调用; 2、可以使用所谓的UMD模式。见下面:
var a = "demo string"; (function (def) { def(window); }(function (global) { console.log(global.a); //"demo string"; }));
section 2 (块级作用域)
1、w ith. 它会将with限定的obj添加到其后代码块的标识符的作用域的前端。
2、 try/catch的catch分句(es3中就有)。用于在不支持let语句条件下人为建立一个块级作用域。
//let 语句形式
let a = 3;
console.log(a);
//catch的实现
{
try {
throw 3;
} catch (a) {
console.log(a);
}
}
3、 let.let不会提升变量,在垃圾收集、闭包(多是循环等)中有重要的作用。
4、 const。这个是建立块级的常量。
{
const a = "inner";
console.log(a); //"inner"
}
console.log(a); //reference error;