for循环中的作用域 闭包
1.作用域的问题
作用域可以简单的理解为作用的范围,一般就是大括号就是一个域,也就是一个范围,一个空间,如果当前这个大括号内找不到变量的初始值,就回去上一级中去找,这里需要注意的有以下三点。
// for i 的作用域
for( var i = 0;i<4; i++){
//TODO
}
console.log(i); // 输出4,也就是 i 的作用域是在外面
// 多个script的情况
<script type="text/javascript">
var name="bonly";
</script>
<script type="text/javascript">
alert(name); // 这里是可以获取上一个script中的name值
</script>
// 通过小括号传参数的作用域
function countPrice(num,price){
// 这里才是num和price的作用域
if(checkNum(num)&&checkPrice(price)){
return num*price;
}
}
function checkNum(num){
return num>0 ? true : false;
}
function checkPrice(price){
return price>0 ? true : false;
}
var num = 8; // 羊肉串的个数
var price = 10; // 羊肉串的单价
console.log(countPrice(num,price)); //输出总价80
2.for循环内想依次获取索引值问题,点击每一个li弹出索引
<ul>
<li>脆皮猪</li>
<li>烤全羊</li>
<li>叫花鸡</li>
</ul>
我们可能会这样写,这里获取的是伪数组,不是真正的数组,具有数组length属性
var ali = document.querySelectorAll('li');
for(var i = 0; i < ali.length; i++) {
ali[i].onclick = function() {
console.log(i); // 输出的结果都是3
}
}
3.这里多了一个大括号,也就是又多了一个域并且这个i在这里并没有定义,需要向上级查找,所以当查到的时候,for循环已经执行完,i的值变成了3。解决方案如下
// 闭包解决
var ali = document.querySelectorAll('li');
for(var i = 0; i < ali.length; i++) {
(function(j) {
ali[j].onclick = function() {
console.log(j); // 依次输出0,1,2
}
})(i);
}
//闭包的作用是把定义的变量保存到内存中,不被销毁,这里是就每次穿过来的i都被j接受并且保存。
闭包还有其他写法,如(funciton()()) !function()() ~function()() 等等
// 给对象添加属性
var ali = document.querySelectorAll('li');
for(var i = 0; i < ali.length; i++) {
ali[i].index=i; // 这一步很关键
ali[i].onclick = function() {
console.log(this.index); // 点击输出索引
}
}