一: 执行环境及作用域 和 变量对象
- var color = "blue";
- function changeColor(){
- var anotherColor = "red";
- // 这里可以访问 color 和 anotherColor
- }
- // 这里只能访问 color
- changeColor();
执行环境是 JavaScript 中最为重要的一个概念. 每个执行环境都有一个与之关联的变量对象(保存执行环境中所有定义的变量和函数). 二:
当代码在执行环境中执行时, 会创建一个作用域链. 作用域链本质是一个指向变量对象的指针列表.
如果执行环境是函数, 则将其活动对象 (最开始时只包含一个变量 ->argument 对象) 作为变量对象. ps:argument 对象在全局环境中是不存在的.
(基于 2 条件下)作用域链中的下一个变量对象来自外部环境, 而再下一个变量对象则来自下下个外部环境. 这样, 一直延续到全局执行环境; 全局执行环境的变量对象始终都是作用域链中的最后一个对象.
image
三: JS 没有块级作用域 **</pre>
- if (true) {
- var color = "blue";
- }
- alert(color); //"blue"
注: 在 JS 中 if 语句中的变量申明会将变量添加到 if 外部的执行环境中(当前是指 Windows 变量); 此时 Windows 变量对象中有一个值是 color = 'blue'
- for (var i=0; i <10; i++){
- doSomething(i);
- }
- alert(i); //10
注: 在 JS 中 for 循环结束后依然会存在循环外部的执行环境中, 即 Windows 变量对象有 i = 10 四:
闭包是指有权访问另一个函数作用域中的变量的函数, 创建闭包的常见方式, 就是在一个函数内部创建另一个函数.
- eg: function createComparisonFunction(propertyName) {
- return function(object1, object2){
- var value1 = object1[propertyName];
- var value2 = object2[propertyName];
- if (value1 < value2){
- return -1;
- } else if (value1> value2){
- return 1;
- } else {
- return 0;
- } // 欢迎加入全栈开发交流圈一起学习交流: 864305860
- };// 面向 1-3 年前端人员
- }// 帮助突破技术瓶颈, 提升思维能力
- // 创建函数
- var compareNames = createComparisonFunction("name");
- // 调用函数
- var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
注: createComparisonFunction()函数返回后, 其执行环境的作用域链会被销毁, 但它的活动对象仍然会留在内存中, 匿名函数的作用域链仍然在引用这个活动对象
以上是作用域链的这种配置机制引出了一个副作用, 即闭包只能获取外部函数任何变量的最后一个值
- function createFunctions(){
- var result = new Array();
- for (var i=0; i < 10; i++){
- result[i] = function(){
- return i;
- };
- }
- console.log(i) // i = 10
- for (var j = 0; j < 10; j++){
- console.log(result[j]()); // 打印 10 个 10
- }
- return result;
- }
- createFunctions();
修改:
- function createFunctions(){
- var result = new Array();
- for (var i = 0; i < 10; i++){
- result[i] = function(num){
- return num;
- }(i);
- console.log(result); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]// 面向 1-3 年前端人员
- return result;// 帮助突破技术瓶颈, 提升思维能力
- }
- createFunctions();