日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解闭包系列第五篇——闭包的10种形式

發(fā)布時(shí)間:2023/12/2 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解闭包系列第五篇——闭包的10种形式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前面的話

  根據(jù)閉包的定義,我們知道,無論通過何種手段,只要將內(nèi)部函數(shù)傳遞到所在的詞法作用域以外,它都會持有對原始作用域的引用,無論在何處執(zhí)行這個(gè)函數(shù)都會使用閉包。接下來,本文將詳細(xì)介紹閉包的10種形式

?

返回值

  最常用的一種形式是函數(shù)作為返回值被返回

var F = function(){var b = 'local';var N = function(){return b;}return N; } console.log(F()());

?

函數(shù)賦值

  一種變形的形式是將內(nèi)部函數(shù)賦值給一個(gè)外部變量

var inner; var F = function(){var b = 'local';var N = function(){return b;};inner = N; }; F(); console.log(inner());

?

函數(shù)參數(shù)

  閉包可以通過函數(shù)參數(shù)傳遞函數(shù)的形式來實(shí)現(xiàn)

var Inner = function(fn){console.log(fn()); } var F = function(){var b = 'local';var N = function(){return b;}Inner(N); } F();

?

IIFE

  由前面的示例代碼可知,函數(shù)F()都是在聲明后立即被調(diào)用,因此可以使用IIFE來替代。但是,要注意的是,這里的Inner()只能使用函數(shù)聲明語句的形式,而不能使用函數(shù)表達(dá)式。詳細(xì)原因移步至此

function Inner(fn){console.log(fn()); }(function(){var b = 'local';var N = function(){return b;}Inner(N); })();

?

循環(huán)賦值

  在閉包問題上,最常見的一個(gè)錯(cuò)誤就是循環(huán)賦值的錯(cuò)誤。關(guān)于其錯(cuò)誤原因的詳細(xì)解釋移步至此

function foo(){var arr = [];for(var i = 0; i < 2; i ){arr[i] = function(){return i;}}return arr; } var bar = foo(); console.log(bar[0]());//2

  正確的寫法如下

function foo(){var arr = [];for(var i = 0; i < 2; i ){arr[i] = (function fn(j){return function test(){return j;}})(i);}return arr; } var bar = foo(); console.log(bar[0]());//0

?

g(s)etter

  我們通過提供getter()和setter()函數(shù)來將要操作的變量保存在函數(shù)內(nèi)部,防止其暴露在外部

var getValue,setValue; (function(){var secret = 0;getValue = function(){return secret;}setValue = function(v){if(typeof v === 'number'){secret = v;}} })(); console.log(getValue());//0 setValue(1); console.log(getValue());//1

?

迭代器

  我們經(jīng)常使用閉包來實(shí)現(xiàn)一個(gè)累加器

var add = (function(){var counter = 0;return function(){return counter; } })(); console.log(add())//1 console.log(add())//2

  類似地,使用閉包可以很方便的實(shí)現(xiàn)一個(gè)迭代器

function setup(x){var i = 0;return function(){return x[i ];} } var next = setup(['a','b','c']); console.log(next());//'a' console.log(next());//'b' console.log(next());//'c'

?

區(qū)分首次

var firstLoad = (function(){var _list = [];return function(id){if(_list.indexOf(id) >= 0){return false;}else{_list.push(id);return true;}} })();firstLoad(10);//true firstLoad(10);//false firstLoad(20);//true firstLoad(20);//false

?

緩存機(jī)制

  通過閉包加入緩存機(jī)制,使得相同的參數(shù)不用重復(fù)計(jì)算,來提高函數(shù)的性能

  未加入緩存機(jī)制前的代碼如下

var mult = function(){var a = 1;for(var i = 0,len = arguments.length; i<len; i ){a = a * arguments[i];}return a; }

  加入緩存機(jī)制后,代碼如下

var mult = function(){var cache = {};var calculate = function(){var a = 1;for(var i = 0,len = arguments.length; i<len; i ){a = a * arguments[i];}return a;};return function(){var args = Array.prototype.join.call(arguments,',');if(args in cache){return cache[args];}
return cache[args] = calculate.apply(null,arguments);} }()

?

img對象

  img對象經(jīng)常用于數(shù)據(jù)上報(bào)

var report = function(src){var img = new Image();img.src = src; } report('http://xx.com/getUserInfo');

  但是,在一些低版本瀏覽器中,使用report函數(shù)進(jìn)行數(shù)據(jù)上報(bào)會丟失30%左右的數(shù)據(jù),也就是說,report函數(shù)并不是每一次都成功地發(fā)起了HTTP請求

  原因是img是report函數(shù)中的局部變量,當(dāng)report函數(shù)的調(diào)用結(jié)束后,img局部變量隨即被銷毀,而此時(shí)或許還沒來得及發(fā)出HTTP請求,所以此次請求就會丟失掉

  現(xiàn)在把img變量用閉包封閉起來,就能解決請求丟失的問題

var report = (function(){var imgs = [];return function(src){var img = new Image();imgs.push(img);img.src = src;} })() report('http://xx.com/getUserInfo');

?


更多專業(yè)前端知識,請上 【猿2048】www.mk2048.com

總結(jié)

以上是生活随笔為你收集整理的深入理解闭包系列第五篇——闭包的10种形式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。