标签:timeout 点击 方式 多个 闭包 创建 ++ 需要 def
what:一个函数能够访问其函数外部作用域中的变量
三大特点:
1.函数嵌套函数
2.内部函数可以访问外部函数的变量
3.参数和变量不会被回收
举例:
function test () {
var a = 1;
return function () {
alert(a);
}
}
var try = test ();
try(); // 弹出a的值
作用:可以通过闭包,设计私有变量及方法
(function(){
var name="wangyu";
Person=function (val) {
name=val;
}
Person.prototype.setName=function(val){
name=val;
}
Person.prototype.getName=function () {
return name;
}
})();
var person1=new Person("sj");
alert(this.name)//undefined 因为在function作用域外不能访问
alert(person1.getName());//sj
var aaa = (function(){
var a = 1;
function bbb(){
a++;
alert(a);
}
function ccc(){
a++;
alert(a);
}
return {
b:bbb, //json结构
c:ccc
}
})();
alert(aaa.a)//undefined
aaa.b(); //2
aaa.c() //3
总结:
1.闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建两一个函数,通过另一个函数访问这个函数的局部变量。
2.闭包的缺点:会常驻内存,会增大内存使用量,使用不当很容易造成内存泄漏
3.其实写的每一个函数都可以算作闭包,即使是全局函数,访问函数外部的全局变量时,就是闭包的体现
常见面试题:
1.for循环中打印
for (var i = 0; i < 4; i++) {
setTimeout(function() {
console.log(i);
}, 300);
}
上边打印出来的都是 4, 可能部分人会认为打印的是 0,1,2,3
原因:js 执行的时候首先会先执行主线程,异步相关的会存到异步队列里,当主线程执行完毕开始执行异步队列, 主线程执行完毕后,此时 i 的值为 4,说以在执行异步队列的时候,打印出来的都是 4(这里需要大家对 event loop 有所了解(js 的事件循环机制))
如何修改使其正常打印:(使用闭包使其正常打印)
//方法一:
for (var i = 0; i < 4; i++) {
setTimeout(
(function(i) {
return function() {
console.log(i);
};
})(i),
300
);
}
2.真实获取多个元素并添加点击事件
var op = document.querySelectorAll("p");
for (var j = 0; j < op.length; j++) {
op[j].onclick = function() {
alert(j);
};
}
//alert出来的值是一样的
// 解决办法一:
for (var j = 0; j < op.length; j++) {
(function(j) {
op[j].onclick = function() {
alert(j);
};
})(j);
}
// 解决办法二:
for (var j = 0; j < op.length; j++) {
op[j].onclick = (function(j) {
return function() {
alert(j);
};
})(j);
}
标签:timeout 点击 方式 多个 闭包 创建 ++ 需要 def
原文地址:https://www.cnblogs.com/jcxfighting/p/11830715.html