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