作用域
-
software security:least exposure
-
naming collision
-
unexpected behavior
-
unintended dependency
-
闭包
-
闭包跟创建的实例相关
-
保存的是变量,可以修改
-
对变量的引用
要素
-
要返回出来一个引用(function)
-
内层作用域要引用外层作用域
-
在其他作用域调用
GC
-
最后一个对这个函数的引用消失,闭包就会被垃圾回收
-
效率、性能
在一个函数中访问另一个函数作用域中变量的方法
闭包的用处
-
函数外部可以访问到函数内部的变量
-
跨作用域,创建私有变量
闭包经典题目结果和改造方式?*
for (var i = 1; i < 9; i++) {
setTimeout(
(function a() {
console.log(i)
},
i * 1000)
)
}
// 利用闭包解决 qaq
for (var i = 1; i < 9; i++) {
(function (j) {
setTimeout(
(function a() {
console.log(j)
},
j * 1000)
)
})(i)
}
// 利用作用域
for (let i = 1; i < 9; i++) {
setTimeout(
(function a() {
console.log(i)
},
i * 1000)
)
}
闭包作用域
var test = (function(i){
return function(){
alert(i*=2);
}
})(2);
test(5);
// alert 输出的结果都会 toString()
// 立即执行函数
// 没有被占用就会销毁
var a=0,
b=0;
function A(a){
A=function(b){
alert(a+b++);
};
alert(a++);
}
A(1);
A(2);
// GO:全局对象
// i++ i不变再++ i再变
// ++i i先变再++
使用场景
-
ajax
-
events
setTimeout
-
原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果
function f1(a) { function f2() { console.log(a); } return f2; } var fun = f1(1); setTimeout(fun,1000);//一秒之后打印出1 12345678
回调
-
定义行为,然后把它关联到某个用户事件上(点击或者按键)。代码通常会作为一个回调事件触发绑定到事件
-
当点击数字时,字体也会变成相应的大小
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> </head> <body> < a href=" " id="size-12">12</ a> < a href="#" id="size-20">20</ a> < a href="#" id="size-30">30</ a> <script type="text/javascript"> function changeSize(size){ return function(){ document.body.style.fontSize = size + 'px'; }; } var size12 = changeSize(12); var size14 = changeSize(20); var size16 = changeSize(30); document.getElementById('size-12').onclick = size12; document.getElementById('size-20').onclick = size14; document.getElementById('size-30').onclick = size16; </script> </body> </html>
函数防抖
封装私有变量
-
用js创建一个计数器
-
方法1:在返回的对象中,用闭包携带了局部变量x,从外部代码根本无法访问到变量x
function f1() { var sum = 0 var obj = { inc: function () { sum++ return sum }, } return obj } let result = f1() console.log(result.inc()) //1 console.log(result.inc()) //2 console.log(result.inc()) //3 -
方法2 qaq
-
所有js数据类型都拥有valueOf和toString这两个方法,null除外
-
valueOf()方法:返回指定对象的原始值
-
toString()方法:返回对象的字符串表示
-
在数值运算中,优先调用了valueOf
-
字符串运算中,优先调用toString
-
sum+'' 是一个字符串类型的数据
-
i++是先赋值,然后再自增;++i是先自增,后赋值
function f1() { var sum = 0 function f2() { sum++ return f2 } f2.valueOf = function () { return sum } f2.toString = function () { return sum + '' } return f2 } //执行函数f1,返回的是函数f2 console.log(+f1()) //0 console.log(+f1()()) //1 console.log(+f1()()()) //2 -
-