红宝书的说法: 变量和函数的上下文决定了它们可以访问哪些数据和它们的行为。每个上下文都有一个关联的变量对象,上面存着定义的变量与方法,无法通过代码访问,后台可以读取。
函数也有其他属性并可以访问
fn.name 函数名称
fn.legnth 函数形参个数
fn.prototype 函数的原型
一、作用域
函数创建时产生的隐式属性[[scope]]
作用 :作用域明确了可访问变量和方法的范围。
[[scope]]保存着scope chain作用域链,作用域链储存的是AO(函数执行上下文)或者GO(全局执行上下文)
函数执行完后,AO会销毁,再调用时,重新创建,AO是即时容器
GO 包含
this -> window
window -> object
document -> object
a ->
AO 包含
this -> 一般为window
arguments -> 类数组
a ->
fn -> function
AO创建过程
function test (a){
var b = 123;
function b (){
}
console.log(a,b)
}
test()
1、给AO添加形参属性,值为undefined
2、给AO添加自定义变量和函数表达式属性,值为undefined
3、给形参赋值
4、函数声明
5、执行其余代码
一个函数创建的时候,作用域链中已经包含了GO全局执行上下文和上级AO,作用域链和外层作用域链一样。
被调用后,预编译的时候,才形成自己的AO,排在作用域链最前面。
function a (){
function b (){}
}
a()
b函数执行完了以后,OA销毁,作用域链回到定义时的状态。a执行完以后,a的AO销毁,AO的b属性也消失了,所以b函数没了。
为什么函数外部不能访问函数内部变量,因为函数外部作用域链中,没有包含函数内部的AO执行期上下文。
为什么函数内部可以访问函数外部变量,因为函数内部作用域链中包含了外层的AO执行期上下文