JavaScript 函数(作用域以及闭包)
JavaScript 函数(作用域以及闭包)
・执行环境及作用域
执行环境定义了变量或函数有权访问的其他数据。
每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量或函数都保存在这个对象中,
虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。
作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问;
作用域的前端始终是当前执行的代码所在环境的变量对象。
・函数表达式
定义函数的两种方式: 函数声明和函数表达式
函数声明的重要特征是函数声明提升,及在执行代码之前会先读取函数声明。
sayHi();
function sayHi() {
......
}
・闭包
概念: 有权访问另一函数作用域中的变量的函数。
function(value1, value2) { if(value1 < value2) { return -1; } else if(value1 > value2) { return 1; } else { return 0; } } var result = compare(5, 10);
闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。
另一个副作用: 闭包只能取得包含函数中任何变量的最后一个值。因为闭包所保存的是整个变量对象,而不是某个特殊的变量。
function createFunctions() { var result = new Array(); for(var i=0; i<10; i++) { result[i] = function() { return i; }; } return result; }
返回的函数数组中的每个函数的返回值都为10。
解决方案
function createFunctions() { var result = new Array(); for(var i=0; i<10; i++) { result[i] = (function(num) { return function() { return alert(num); }; })(i); } return result; }
・this对象
全局函数中,this等于window;
函数被作为某个对象的方法调用时,this等于那个对象;
匿名函数的执行环境具有全局性,this通常指向window。
var name = "The Window"; var object = { name: "My Object", getNameFunc: function() { return function() {this.name;}; } }; alert(object.getNameFunc()()); // 执行结果: The Window
第一步 object.getNameFunc()作为函数方法调用,this指向的是object;
第二步 object.getNameFunc()()作为匿名函数调用,this指向的是window;