js面试题知识点全解(一闭包)
闭包使用场景:
1.函数作为返回值,如下场景
1 function F1(){ 2 var a = 100 //自由变量 3 //返回一个函数(函数作为返回值) 4 return function(){ 5 console.log(a) //a是定义的时候 的作用域,不是执行的时候的作用域,为100 6 } 7 } 8 //f1得到一个函数 9 var f1 = F1() 10 var a = 200 //全局作用域,不影响函数内作用域 11 f1()
2.函数作为参数传递
1 function F1(){ 2 var a = 100 //自由变量 3 return function(){ 4 console.log(a) //自由变量,父作用域寻找 5 } 6 } 7 var f1 = F1() 8 function F2(fn){ 9 var a =300 10 fn() 11 } 12 F2(f1) //输出100
3.实际开发中闭包的应用:
闭包实际应用中主要用于封装变量,收敛权限
1 function isFirstLoad(){ 2 var _list = [] //放在函数内部,封装变量,使外部无法修改 3 return function (id){ 4 if (_list.indexOf(id) >= 0){ //indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。 5 return false 6 }else{ 7 _list.push(id) 8 return true 9 } 10 } 11 } 12 13 //使用 14 var firstLoad = isFirstLoad() 15 firstLoad(10) //true 16 firstLoad(10) //false 17 firstLoad(20) //true
实例:创建10个a标签,点击哪个弹出哪个数字
错误写法:
1 //错误写法 2 var i,a 3 for( i = 0; i<10; i++){ 4 a = document.createElement('a') 5 a.innerHTML=i+'<br/>' 6 a.addEventListener('click',function(e){ 7 e.preventDefault() //preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交)。 8 alert(i) //i都是10,i是自由变量,要去父作用域(全局作用域)获取值,此时i已执行完,值为10 9 }) 10 document.body.appendChild(a) 11 }
正确写法:
1 var i 2 14 for( i = 0; i<10; i++){ 3 15 (function(i){ 4 16 var a = document.createElement('a') 5 17 a.innerHTML=i+'<br/>' 6 18 a.addEventListener('click',function(e){ 7 19 e.preventDefault() //preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交)。 8 20 alert(i) 9 21 }) 10 22 document.body.appendChild(a) 11 23 })(i) //创建一个自执行函数 12 24 }