02函数-03-闭包
生活随笔
收集整理的這篇文章主要介紹了
02函数-03-闭包
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1、閉包的概念
閉包是一種特殊的程序結(jié)構(gòu),即 函數(shù)A中定義了另一個(gè)函數(shù)a,內(nèi)部函數(shù)a引用了外部函數(shù)A的參數(shù)和局部變量,最終A會返回一個(gè)保存了相關(guān)參數(shù)和變量的函數(shù)a。簡潔地說,外層函數(shù)將保存了信息的可執(zhí)行內(nèi)層函數(shù)作為結(jié)果返回。
來看個(gè)例子://求和功能 function lazy_sum(arr) {var sum = function () {return arr.reduce(function (x, y) {return x + y;});}return sum; } //當(dāng)調(diào)用該函數(shù)時(shí)不會直接返回結(jié)果,而是返回函數(shù) --e.g.--> // var f = lazy_sum([1, 2, 3, 4, 5]); --> 得到 function sum() //調(diào)用函數(shù)時(shí),才得到真正的結(jié)果 --e.g.--> // f(); --> 得到 15 //另,即使傳入相同參數(shù)的兩個(gè)函數(shù)A,返回的函數(shù)a也是不同的121//求和功能 ?2function lazy_sum(arr) {3 ? ?var sum = function () {4 ? ? ? ?return arr.reduce(function (x, y) {5 ? ? ? ? ? ?return x + y;6 ? ? ? });7 ? }8 ? ?return sum;9}10//當(dāng)調(diào)用該函數(shù)時(shí)不會直接返回結(jié)果,而是返回函數(shù) --e.g.--> // var f = lazy_sum([1, 2, 3, 4, 5]); --> 得到 function sum()11//調(diào)用函數(shù)時(shí),才得到真正的結(jié)果 --e.g.--> // f(); --> 得到 1512//另,即使傳入相同參數(shù)的兩個(gè)函數(shù)A,返回的函數(shù)a也是不同的
2、閉包的小坑
閉包的返回函數(shù),是沒有立刻執(zhí)行的,直到調(diào)用該函數(shù)才會執(zhí)行,這意味著,如果是引用了循環(huán)變量,會變成如下情況:function count() {var arr = [];for (var i=1; i<=3; i++) {arr.push(function () {return i * i;});}return arr; }var results = count(); var f1 = results[0]; var f2 = results[1]; var f3 = results[2];//然而f1(),f2(),f2()的結(jié)果并不是1,4,9,而全部是16161function count() {2 ? ?var arr = [];3 ? ?for (var i=1; i<=3; i++) {4 ? ? ? ?arr.push(function () {5 ? ? ? ? ? ?return i * i;6 ? ? ? });7 ? }8 ? ?return arr;9}1011var results = count();12var f1 = results[0];13var f2 = results[1];14var f3 = results[2];1516//然而f1(),f2(),f2()的結(jié)果并不是1,4,9,而全部是16原因就在于返回的函數(shù)引用了變量i,但它并非立刻執(zhí)行。等到3個(gè)函數(shù)都返回時(shí),它們所引用的變量i已經(jīng)變成了4,因此最終結(jié)果為16。
如果一定要引用循環(huán)變量,需要再創(chuàng)建一個(gè)函數(shù),用該函數(shù)的參數(shù)綁定當(dāng)前循環(huán)變量的值:function count() {var arr = [];for (var i=1; i<=3; i++) {arr.push((function (n) {return function () {return n * n;}})(i));}return arr; }var results = count(); var f1 = results[0]; var f2 = results[1]; var f3 = results[2];f1(); // 1 f2(); // 4 f3(); // 9201function count() {2 ? ?var arr = [];3 ? ?for (var i=1; i<=3; i++) {4 ? ? ? ?arr.push((function (n) {5 ? ? ? ? ? ?return function () {6 ? ? ? ? ? ? ? ?return n * n;7 ? ? ? ? ? }8 ? ? ? })(i));9 ? }10 ? ?return arr;11}1213var results = count();14var f1 = results[0];15var f2 = results[1];16var f3 = results[2];1718f1(); // 119f2(); // 420f3(); // 9這里用到了一個(gè)語法 “創(chuàng)建一個(gè)匿名函數(shù)并立即執(zhí)行”:(function (x) {return x * x; })(3); // 9 //由于JavaScript語法解析的問題,會報(bào)SyntaxError錯(cuò)誤,因此需要用括號把整個(gè)函數(shù)定義括起來41(function (x) {2 ? ?return x * x;3})(3); // 94//由于JavaScript語法解析的問題,會報(bào)SyntaxError錯(cuò)誤,因此需要用括號把整個(gè)函數(shù)定義括起來
3、閉包的意義
上面我們講到,閉包相當(dāng)于把傳參后的函數(shù)進(jìn)行了保存但是并不會立刻執(zhí)行,你要調(diào)用返回的這個(gè)函數(shù)才會執(zhí)行,所以說閉包的意義只是在于延遲執(zhí)行函數(shù)嗎?當(dāng)然不完全是這樣,還有其他很多功能。在例如Java中,我們要封裝一個(gè)私有變量,只需要加上private關(guān)鍵字就可以了,可是在JS中,我們也想要封裝一個(gè)私有變量,怎么辦?利用閉包。//e.g.創(chuàng)建一個(gè)計(jì)數(shù)器 function create_counter(initial) {var x = initial || 0;return {inc: function () {x += 1;return x;}} }101//e.g.創(chuàng)建一個(gè)計(jì)數(shù)器2function create_counter(initial) {3 ? ?var x = initial || 0;4 ? ?return {5 ? ? ? ?inc: function () {6 ? ? ? ? ? ?x += 1;7 ? ? ? ? ? ?return x;8 ? ? ? }9 ? }10}
閉包中攜帶了局部變量x,但是當(dāng)你使用該函數(shù)時(shí),你實(shí)際上是無法訪問到變量x的,即實(shí)際上這個(gè)函數(shù)的狀態(tài)完全被隱藏了:var c1 = create_counter(); c1.inc(); // 1 c1.inc(); // 2 c1.inc(); // 3var c2 = create_counter(10); c2.inc(); // 11 c2.inc(); // 12 c2.inc(); // 1391var c1 = create_counter();2c1.inc(); // 13c1.inc(); // 24c1.inc(); // 356var c2 = create_counter(10);7c2.inc(); // 118c2.inc(); // 129c2.inc(); // 13
閉包還可以創(chuàng)建新函數(shù),例如把多參數(shù)的函數(shù)變成單參數(shù)的函數(shù)。例如,要計(jì)算x的y次方可以用Math.pow(x, y)函數(shù),不過考慮到經(jīng)常計(jì)算x平方或x立方,我們可以利用閉包創(chuàng)建新的函數(shù)pow2和pow3:
function make_pow(n) {return function (x) {return Math.pow(x, n);} }// 創(chuàng)建兩個(gè)新函數(shù): var pow2 = make_pow(2); var pow3 = make_pow(3);pow2(5); // 25 pow3(7); // 343x1function make_pow(n) {2 ? ?return function (x) {3 ? ? ? ?return Math.pow(x, n);4 ? }5}67// 創(chuàng)建兩個(gè)新函數(shù):8var pow2 = make_pow(2);9var pow3 = make_pow(3);1011pow2(5); // 2512pow3(7); // 343
轉(zhuǎn)載于:https://www.cnblogs.com/deng-cc/p/6622610.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的02函数-03-闭包的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql exist 优化查询时间
- 下一篇: 庖丁解牛-----Live555源码彻底