# 作用域链

要理解变量作用域和作用域链,js中没有块级作用域。

var scope = "global scope"
function checkscope() {
	var scope = "local scope"
	function f() { return scope }
	return f()
}
console.log(checkscope());

上述代码输出 local scope ,因为函数f是在函数checkscope中定义的,根据作用域链,先从f中寻找scope,如果没有找到,则向上查找,找到checkscope中的scope,即 local scope。

var scope = "global scope"
function checkscope() {
	function f() { return scope }
	return f()
}
console.log(checkscope());

同理这段代码也一样,这段代码输出 global scope,因为f和checkscope中都找不到scope,那么就继续向上找,找到全局对象中,发现scope为global scope。

function test() {
	var count = 0
	function f() { return count++ }
	return f
}

a = test()
console.log(a());
console.log(a());

上述代码中嵌套函数f被当作返回值返回给a,此时它就不会被当作垃圾处理,同时f的count依赖于test的count,因此test也不会被当作垃圾处理。因此代码运行结果为0和1。

# 闭包的作用

有很多地方都会使用到闭包,例如异步编程、模块化、ajax请求、事件监听等回调函数就在使用闭包。

function wait(message) {
	setTimeout(function timer() {
		console.log(message);
	}, 1000);
}

wait("Hello world")

wait执行1s后,它的内部作用于并不会消失,仍然会输出Hello world。

# 闭包会引起内存泄漏

滥用闭包,导致许多引用变量不会被回收,就会引起内存泄漏,所以当闭包作用域链中保存的引用变量不需要的时候,应设置为null,解除引用确保正常回收其占用的内存。

function assignHandler(){
    var element = $('id');
    var id = elment.id;
 
    element.onclick = function(){
        alert(id);
    };
    element = null;
}