js閉包的9個(gè)使用場(chǎng)景
1.返回值(最常用)
//1.返回值 最常用的
function fn(){
var name="hello";
return function(){
return name;
}
}
var fnc = fn();
console.log(fnc())//hello
這個(gè)很好理解就是以閉包的形式將 name 返回。
2.函數(shù)賦值
var fn2;
function fn(){
var name="hello";
//將函數(shù)賦值給fn2
fn2 = function(){
return name;
}
}
fn()//要先執(zhí)行進(jìn)行賦值,
console.log(fn2())//執(zhí)行輸出fn2
在閉包里面給fn2函數(shù)設(shè)置值,閉包的形式把name屬性記憶下來(lái),執(zhí)行會(huì)輸出 hello。
3.函數(shù)參數(shù)
function fn(){
var name="hello";
return function callback(){
return name;
}
}
var fn1 = fn()//執(zhí)行函數(shù)將返回值(callback函數(shù))賦值給fn1,
function fn2(f){
//將函數(shù)作為參數(shù)傳入
console.log(f());//執(zhí)行函數(shù),并輸出
}
fn2(fn1)//執(zhí)行輸出fn2
用閉包返回一個(gè)函數(shù),把此函數(shù)作為另一個(gè)函數(shù)的參數(shù),在另一個(gè)函數(shù)里面執(zhí)行這個(gè)函數(shù),最終輸出 hello
4.IIFE(自執(zhí)行函數(shù))
(function(){
var name="hello";
var fn1= function(){
return name;
}
//直接在自執(zhí)行函數(shù)里面調(diào)用fn2,將fn1作為參數(shù)傳入
fn2(fn1);
})()
function fn2(f){
//將函數(shù)作為參數(shù)傳入
console.log(f());//執(zhí)行函數(shù),并輸出
}
直接在自執(zhí)行函數(shù)里面將封裝的函數(shù)fn1傳給fn2,作為參數(shù)調(diào)用同樣可以獲得結(jié)果 hello
5.循環(huán)賦值
//每秒執(zhí)行1次,分別輸出1-10
for(var i=1;i<=10;i++){
(function(j){
//j來(lái)接收
setTimeout(function(){
console.log(j);
},j*1000);
})(i)//i作為實(shí)參傳入
}
如果不采用閉包的話(huà),會(huì)有不一樣的情況,可以看我自己 閉包 的文章。
6.getter和setter
function fn(){
var name='hello'
setName=function(n){
name = n;
}
getName=function(){
return name;
}
//將setName,getName作為對(duì)象的屬性返回
return {
setName:setName,
getName:getName
}
}
var fn1 = fn();//返回對(duì)象,屬性setName和getName是兩個(gè)函數(shù)
console.log(fn1.getName());//getter
fn1.setName('world');//setter修改閉包里面的name
console.log(fn1.getName());//getter
第一次輸出 hello 用setter以后再輸出 world ,這樣做可以封裝成公共方法,防止不想暴露的屬性和函數(shù)暴露在外部。
7.迭代器(執(zhí)行一次函數(shù)往下取一個(gè)值)
var arr =['aa','bb','cc'];
function incre(arr){
var i=0;
return function(){
//這個(gè)函數(shù)每次被執(zhí)行都返回?cái)?shù)組arr中 i下標(biāo)對(duì)應(yīng)的元素
return arr[i++] || '數(shù)組值已經(jīng)遍歷完';
}
}
var next = incre(arr);
console.log(next());//aa
console.log(next());//bb
console.log(next());//cc
console.log(next());//數(shù)組值已經(jīng)遍歷完
8.首次區(qū)分(相同的參數(shù),函數(shù)不會(huì)重復(fù)執(zhí)行)
var fn = (function(){
var arr=[];//用來(lái)緩存的數(shù)組
return function(val){
if(arr.indexOf(val)==-1){//緩存中沒(méi)有則表示需要執(zhí)行
arr.push(val);//將參數(shù)push到緩存數(shù)組中
console.log('函數(shù)被執(zhí)行了',arr);
//這里寫(xiě)想要執(zhí)行的函數(shù)
}else{
console.log('此次函數(shù)不需要執(zhí)行');
}
console.log('函數(shù)調(diào)用完打印一下,方便查看已緩存的數(shù)組:',arr);
}
})();
fn(10);
fn(10);
fn(1000);
fn(200);
fn(1000);
執(zhí)行結(jié)果如下:

可以明顯的看到首次執(zhí)行的會(huì)被存起來(lái),再次執(zhí)行直接取。
9.緩存
//比如求和操作,如果沒(méi)有緩存,每次調(diào)用都要重復(fù)計(jì)算,采用緩存已經(jīng)執(zhí)行過(guò)的去查找,查找到了就直接返回,不需要重新計(jì)算
var fn=(function(){
var cache={};//緩存對(duì)象
var calc=function(arr){//計(jì)算函數(shù)
var sum=0;
//求和
for(var i=0;i<arr.length;i++){
sum+=arr[i];
}
return sum;
}
return function(){
var args = Array.prototype.slice.call(arguments,0);//arguments轉(zhuǎn)換成數(shù)組
var key=args.join(",");//將args用逗號(hào)連接成字符串
var result , tSum = cache[key];
if(tSum){//如果緩存有
console.log('從緩存中?。?,cache)//打印方便查看
result = tSum;
}else{
//重新計(jì)算,并存入緩存同時(shí)賦值給result
result = cache[key]=calc(args);
console.log('存入緩存:',cache)//打印方便查看
}
return result;
}
})();
fn(1,2,3,4,5);
fn(1,2,3,4,5);
fn(1,2,3,4,5,6);
fn(1,2,3,4,5,8);
fn(1,2,3,4,5,6);
輸出結(jié)果:

以上就是js閉包的9個(gè)使用場(chǎng)景的詳細(xì)內(nèi)容,更多關(guān)于js 閉包使用場(chǎng)景的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS驗(yàn)證日期的格式Y(jié)YYY-mm-dd 具體實(shí)現(xiàn)
這篇文章介紹了JS對(duì)日期格式的驗(yàn)證實(shí)例,有需要的朋友可以參考一下2013-06-06
JavaScript中object和Object的區(qū)別(詳解)
下面小編就為大家?guī)?lái)一篇JavaScript中object和Object的區(qū)別(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
layui table表格數(shù)據(jù)的新增,修改,刪除,查詢(xún),雙擊獲取行數(shù)據(jù)方式
今天小編就為大家分享一篇layui table表格數(shù)據(jù)的新增,修改,刪除,查詢(xún),雙擊獲取行數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
JS實(shí)現(xiàn)微信"炸屎"大作戰(zhàn)功能
這篇文章主要介紹了JS實(shí)現(xiàn)微信 "炸屎"大作戰(zhàn),本文通過(guò)實(shí)例代碼圖文展示給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07

