JS作用域理解
看书总结的个人理解,欢迎指正,共同进步~~
JavaScript被归类为解释执行的编译语言, JavaScript采用的是词法作用域原型,在代码编写时,作用域就确定下来.学过编译可知,会在源程序运行边解释边运行,类比”口译”,但js中提供了在词法分析后依旧可以修改作用域的方法:
-
eval( )函数 在参数中修改的函数,被动态加入修改作用域
function print(a,b){
eval(a);
console.log(a,b)
}
var c=2;
print("var c=1",10); //1 10
- with 关键字 with(obj){…}
-
为obj创建新的作用域,若obj没有{}内部的属性k, obj.k值为undefined不会创建新属性,非严格模式下会创建全局属性.
以上两种方法会导致性能下降,很难优化.作用域
ES5中只全局和函数级作用域
基于最小暴露原则,我们通过匿名函数(不具名可减少对全局的污染),立即执行函数(IIFE)将代码包装起来.在ES6中,引入块级作用域- let声明:之前只有var 和 function声明 使用let后,将变量绑定到let所在{}内部
- with :上面有提到
- try/catch中: 在catch分句内部声明的仅在其中有效
- const: 注意声明一个常量不可再更改,声明时即赋值.const声明的对象为地址时,要保证地址不变,但可以修改对象.
通过块级作用域,可以不使用IIFE~~
要注意const和let没有声明提升;且不可重复声明,会报错.提升
- 函数,var定义的变量声明会提升,但赋值操作不会,执行时通过LHS找到目标才操作.
- 函数声明未定义,导致ReferenceError;未声明则是TypeError.
- 以function开始,被认为是函数声明,可以提升,而其他被认为是函数表达式,不提升导致不是一个函数(typeError)
关于this
this是运行才会绑定对象,动态变化的,但首先明确this翻译是这个,但”这个”并非函数本身,在<<你不知道的JavaScript>>中看到一个有意思的例子
function foo(){ var a=2; this.bar(); } function bar(){ console.log(this.a); } foo() //ReferenceError a is not defined
错误:
1.为了让bar的this指向自身,foo()错误地在bar()前面加了this.这里可以直接调用
2.bar函数内部使用this使用foo的a变量,但作用域不可以通过js联通访问,可以当作参数传递.