要搞懂闭包首先得搞懂什么是作用域,作用域分为全局作用域和局部(函数)作用域,每个作用域都有与他关联的变量对象(定义的所有变量和函数),作用域简单理解就是变量执行时的环境。
当代码在一个环境中执行时,会创建变量对象的一个作用域链,作用域链最前端是当前执行代码的所在的环境变量对象。之后是他的外部作用域,之后是外部的外部作用域,直到作用域链终点为全局执行环境。
var name = 'kayle'
function getName () {
// var name = 'innerKayle'
console.log(name) // kayle
}
getName()
函数getName
当他被调用时会创建一个执行环境及相应的作用域链,然后arguments和其他命名参数的值来初始化函数的活动对象。可以在函数内部访问到变量name
,是因为能够在作用域链中找到它。
闭包是一个定义在其他函数内部的函数,他由函数及创建该函数的词法环境组合而成,这个环境包含了这个闭包创建时所能访问的所有局部变量。闭包可以访问三种作用域中的变量:
外部调用函数完毕后,作用域链中任然占用其内部函数对象,会使得内部父函数中的变量也都被保存在内存中,内存消耗很大(直到解除该函数的引用)。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()()); //The Window
这里之所以输出了The Window
是因为原型链中找到了全局中的变量name
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); //My Object
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
this.getName = function() {
return this.name;
};
this.getMessage = function() {
return this.message;
};
}
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype.getName = function() {
return this.name;
};
MyObject.prototype.getMessage = function() {
return this.message;
};