1-- 闭包的认识:
闭包可以让函数访问所有的变量和函数,只要这些变量和函数存在于该函数声明时的作用于内就行。
var outerValue = '包治百病'; //#1
function outerFunction() {
console.log(outerValue); //#2
console.log(laterValue); //#3
}
var laterValue=在函数之后定义的值";
outerFunction(); //#4
console.log(qi); //#5
var qi="你不知道的JavaScript";
上面是一个简单的闭包,说明问题:#2和#3都能打印出来相应的值,而#5是undefined;下面是关于闭包的有趣概念:
|. 作用于之外的所有变量,即便是函数声明之后的那些声明,也都包含在闭包中。
||.相同作用于内,尚未声明的变量不能进行提前引用。
|||.尽管闭包十分有用,但是他们的使用并非完全没有开销,比暴力的信息会一直保存在内存里,直到这些信息确保不再被使用,或页面卸载时,JavaScript引擎才能清理这些信息。
2 --下面介绍一下闭包的使用
1.私有变量
function Ninja() { //#1
var feints = 0; //#2
this.getFeints = function(){ //#3
return feints; //#3
}; //#3
this.feint = function(){ //#4
feints++; //#4
}; //#4
}
var ninja = new Ninja(); //#5
ninja.feint(); //#6
console.log(ninja.getFeints());
if(ninja.feint === undefined){ //#7
console.log("不可以访问到feints"); //#7
}
if(ninja.getFeints() == 1){ //#8
console.log("可以访问内部私有变量") //#8
}
上面例子得到的结果是:"可以访问到内部私有变量".所以有,可以通过存取方法获取私有变量的值,但是不能直接访问私有变量。
2.绑定函数上下文:
先看下面的这个小例子出现的问题:
<button id="test">Click Me!</button>
<script>
var button = { //#2
clicked: false,
click: function(){ //#3
this.clicked = true;
console.log(button.clicked); //#4
console.log(this); //#4-1
}
};
var elem = document.getElementById("test"); //#5
elem.addEventListener("click",button.click,false); //#5
</script>
这里面使用#4打印出来的结果是false,而不是true;#4-1打印出来的this是button这个元素,而不是button这个对象;因为DOM2级事件处理程序和DOM0级的事件处理程序都是依附在元素的作用于里面运行的,也就是说,绑定后,this指向的是button这个元素,而不是button对象,所以会打印出来上面的结果。
接着,我们来介绍一个通过使用闭包来绑定函数上下文的例子:
<button id="test">Click Me!</button>
<script>
function bind(context,name){ //#1
return function(){ //#1
return context[name].apply(context,arguments); //#1
}; //#1
} //#1
var button = {
clicked: false,
click: function(){
this.clicked = true;
assert(button.clicked,"The button has been clicked");
console.log(this);
}
};
var elem = document.getElementById("test");
elem.addEventListener("click",bind(button,"click"),false); //#2
</script>
这里面特别精髓的地方就是那个bind函数了,这个方法创建并返回一个匿名函数,该匿名函数使用apply()调用了原始函数。
|.bind函数的context参数就是 -- 要设置的上下文对象
||.bind函数的name参数就是 -- 方法名称
网友评论