执行环境
执行环境,又叫执行上下文(execution context),定义了变量或函数有权访问的其他数据,决定了它们各自的行为,可以看成一个对象
executionContextObj = {
scopeChain: { /* 作用域链:变量对象+ 所有父执行上下文的变量对象*/ },
variableObject: { /*变量对象:函数 arguments/参数,内部变量和函数声明 */ },
this: { /*运行这个函数的对象(动态的) */ }
}
牢记下面几点:
- 所有的js代码都在某个执行环境中运行的。
- 作用域链是对执行环境中的变量对象有序访问的链表,包括了当前执行环境的变量对象和所有父级执行环境的变量对象。作用域链在函数创建时就已经确定,而不是在函数运行时确定。
- this在函数运行时确定, 指向一个环境对象,注意是一个对象,而且是一个普通对象,而不是一个执行环境。
作用域(Scope)
作用域就是变量与函数的可访问范围,Scope分为Lexical Scope和Dynamic Scope。JavaScript采用Lexical Scope,即Scope在我们写代码的时候就被定义好了。
this
在函数执行时,this 总是指向调用该函数的对象。要判断 this 的指向,其实就是判断 this 所在的函数属于谁。
this 出现的场景分为四类,简单的说就是:
- 有对象就指向调用对象
- 没调用对象就指向全局对象
- 用new构造就指向新对象
- 通过 apply 或 call 或 bind 来改变 this 的所指。
闭包
闭包就是能够读取其他函数内部变量的函数。
它的用处主要有两个:
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
既然是可以读取函数内部的变量,为什么不直接return一个变量n,而是return一个函数呢,因为return变量n的话是可以读取变量,但是函数运行完,这个变量会被垃圾回收机制回收,下次运行这个函数,只会重新创建一个变量。