函数作用域[scope]
- 外部对内部可见;
- 内部对外部不可见;
- 内部优先
JS中只有函数级别的作用域,没有块级别的作用域;换句话说,只有在进入或者退出函数的时候,作用域会发生变化。
1、外部对内部可见
<script>
var scope='g';
function t(){
console.log(scope);
// var scope="l";
console.log(scope);
}
t();
</script>
结果 g g
2、内部堆外部不可见
<script>
function t(){
var scope="l";
}
t();
console.log(scope);
</script>
3、都可见时,内部优先
<script>
var scope='g';
function t(){
console.log(scope);
var scope="l";
console.log(scope);
}
t();
</script>
4、JS的作用域,都是函数级别的。
<script>
var scope='g';
if(true){
var scope="l";
console.log(scope);
}
console.log(scope);
</script> //如果C或C++ 最后一个console 结果时g,
for(var i=0;i<10;i++){
}
console.log(i); //10
执行环境和作用域链
执行环境(execution context),定义了执行期间可以访问的变量和函数。
1、全局执行环境
- Global Object(window)
- 从见到js代码开始创建
- 到网页关闭时销毁
2、函数执行环境
- Activation Object
- 从函数调用开始创建
- 到函数调用结束时销毁
执行环境(EC)和作用域链
1、作用域[scope],每个函数都有。
2、作用域是自由属性,只能由JS引擎访问。
3、作用域链,是AO和GO构成的链
4、所谓执行环境,就是根据作用域链一次查找变量和函数。
- 找到即停;
- 全部找完无果,报错。
5、作用域链每个函数都有
每个函数在定义(函数声明\函数表达式)时会拷贝其父亲函数的作用域链;
在函数被调用时,生成AO然后将AO压入作用域链的栈顶。
执行fa()函数时
执行fb()时
<script>
//函数多次调用时,时产生相同的AO还是不同的AO?
// 答:不同;
//函数递归调用时,时产生相同的AO还是不同的AO?
//答:不同;
</script>
其他生成作用域链的方式
with,生成行的with variable object
,放在作用域链表顶端
person={
name:"yhb",age:22,height:175,
wife:{name:"lwy",age:21}
}
with(person){
console.log(name);
}
with(person.wife){
console.log(name);
}
作用域链的注意点
效率:尽量少使用靠近上层的变量。多使用自己局部的变量。
重名,容易出错:尽量减少不同层次函数使用相同的变量名。避免函数名与变量名一样