1.带参闭包问题
function foo(x) {
var tmp = 3;
return function f2(y) {
alert(x + y + (++tmp));
};
}
var bar = foo(3); // bar 现在是一个闭包
bar(10);
注:首先执行var bar = foo(3);那么foo就执行了,参数3也传进去了,但是执行完毕后,tmp变量以及参数x就已经被释放回收了吗?
并没有,因为返回值里面还等待使用这些变量,所以此时,foo虽然执行了,但是foo的变量并没有被释放,在return中等待继续使用这些变量,这时bar就是一个闭包。
2.事件闭包问题
例:很多元素绑定一个点击事件
点击每个按钮时拿到当前按钮所对应的索引值
CSS样式如下:
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
首先看拿不到在for循环里当前对象的i值的写法:
var btn = document.getElementsByClassName("btn");
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
alert(i);
}
}
注:网页初始化时,每个按钮的事件都已经绑好了,用户触发都是后续触发的,后续触发说明事件有了,事件有了说明for循环执行完成,i就已经拿到最大值。
问题:怎样在for循环里拿到当前对象的i值
解决:索引对索引
写法一:参数的传递
var btn = document.getElementsByClassName("btn");
for (var i = 0; i < btn.length; i++) {
//参数的传递 桥梁
btn[i].index = i;
btn[i].onclick = function () {
alert(this.index);
}
}
写法二:自执行函数的闭包 自执行函数的参是后面跟括号里的参数传的
var btn = document.getElementsByClassName("btn");
for (var i = 0; i < btn.length; i++) {
(function (x) {
btn[i].onclick = function () {
alert(x);
}
})(i); //这个i是for循环的i
}
注:for循环每一次都执行一个自执行函数,每一次变量i被当做参数传到IIEF(自执行函数)中去,那么这个IIEF中创建了一个变量参数x,然后元素节点btn绑定了一个onclick事件,执行函数里面需要用到这个参数x,但是你又没点,那么这个变量x就没有被清理,就一直在参数里面被保存着,每一个IIEF都做一样的事情,所以这个时候就产生了闭包,变量x并没有被回收,依然在等待使用。
3.面向对象
function fun(n, o) {
console.log(o)
return {
fun: function (m) {
return fun(m, n);
}
};
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
4.首先解释arguments
arguments指当前函数的参数列表,类似于数组的集合,使用索引值取;
arguments.length返回当前参数列表的长度
function f1(a, b, c) {
console.log(arguments[0]); //4
console.log(arguments.length); //3
}
f1(4, 5, 6);
例:
function f1(a, b, c) {
/*arguments 是当前函数的参数列表 类似于数组的集合 使用索引值来取*/
console.log(arguments.length);
}
f1(1, 2, 3);
var sum = function () {
var cache;
if (arguments.length === 1) {
cache = arguments[0]; //如果arguments对象的长度为1,也就是参数只有1个时,将这个参数赋值给cache,暂存
return function (number) { //返回一个函数,函数里的参数(也就是第二个括号里的参数)与之前第一个括号里的参数相加
return cache + number
}
} else {
return arguments[0] + arguments[1]; //如果arguments对象的长度不为1,那么两个参数相加
}
}
console.log(sum(2, 3)); //5
console.log(sum(2)(3)); //5