首先我们需要明白什么是执行环境?什么是函数的作用域?
1. 执行环境定义了变量和函数有权访问的其他数据。
每个执行环境都有一个与之关联的变量对象,环境中定影的所有的变量和函数均保存在这个变量对象中。
每个函数都有自己的执行环境。当执行流进入一个函数中,函数的环境进入一个环境栈,函数执行完毕,栈将其环境推出。
2. 作用域保证对执行环境有权访问的所有变量和函数的有序访问。
当进入一个执行环境,环创建变量对象的作用域链。
作用域链的前端始终是当前执行的代码所在的执行环境的变量对象确定应该何时释放内存。
变量的执行环境有助于
var animal = "dog";
function changeAnimal(){
if(animal == "dog"){
animal = "cat"
}
}
changeAnimal();
console.log("Current animal is :"+animal); //cat
上述代码中,changeAnimal()的作用域链包含两个对象,自己的局部环境的变量和全局环境的变量。能够访问animal就是因为在作用域链中可以找到animal。
内部环境可以通过作用域链访问所有的外部变量,外部环境不能访问内部环境的变量和函数。
但是有其他的办法延长作用域链。
- with
- try-catch语句的catch
3. JS没有块级作用域
例如:
if(true){
var flag = false;
}
console.log(flag); //false,不报错
for(var i = 0;i<10;i++){
//doSomething
}
console.log(i); // 10
这是因为使用var 定义的变量会被添加到最近的执行环境中,上述代码中即全局环境,所以不会报错,正常输出。
再例如:
function doAdd(num1,num2){
var result = num1 +num2;
return result;
}
var sum = doAdd(10,10);
console.log(sum); //20
console.log(result); //报错
使用var 声明变量result,其被添加进最近的执行环境,即函数的局部环境,所以在全局环境中不会访问到result,所以最后一句代码会报错。
这个例子中,如果省略var关键字,则最后一句代码会正常执行,输出结果20.
这是因为不使用var定义的变量会被添加进全局环境。
如果在全局环境和函数局部环境定义了相同名称的变量,调用函数时使用的是局部环境定义的变量。
例如:
var animal = "dog";
function getAnimal(){
var animal = "cat";
//想要在函数内访问全局变量animal需要使用window.animal
return animal;
};
getAnimal(); //"cat"
欢迎大家一起讨论,进步!!!