标签: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