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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

前面的話

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

?

返回值

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

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

?

函數賦值

  一種變形的形式是將內部函數賦值給一個外部變量

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

?

函數參數

  閉包可以通過函數參數傳遞函數的形式來實現

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

?

IIFE

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

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

?

循環賦值

  在閉包問題上,最常見的一個錯誤就是循環賦值的錯誤。關于其錯誤原因的詳細解釋移步至此

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()函數來將要操作的變量保存在函數內部,防止其暴露在外部

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

?

迭代器

  我們經常使用閉包來實現一個累加器

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

  類似地,使用閉包可以很方便的實現一個迭代器

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'

?

區分首次

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

?

緩存機制

  通過閉包加入緩存機制,使得相同的參數不用重復計算,來提高函數的性能

  未加入緩存機制前的代碼如下

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

  加入緩存機制后,代碼如下

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對象經常用于數據上報

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

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

  原因是img是report函數中的局部變量,當report函數的調用結束后,img局部變量隨即被銷毀,而此時或許還沒來得及發出HTTP請求,所以此次請求就會丟失掉

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

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

?


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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。