Js閉包的實現原理和作用


閉包的實現原理和作用

1、閉包的概念:指有權訪問另一個函數作用域中的變量的函數,一般情況就是在一個函數中包含另一個函數。

2、閉包的作用:訪問函數內部變量、保持函數在環境中一直存在,不會被垃圾回收機制處理

因為函數內部聲明 的變量是局部的,只能在函數內部訪問到,但是函數外部的變量是對函數內部可見的,這就是作用域鏈的特點了。

子級可以向父級查找變量,逐級查找,找到為止

function bar(){ //外層函數聲明的變量 var value=1; function foo(){ console.log(value); } return foo(); }; var bar2=bar; //實際上bar()函數並沒有因為執行完就被垃圾回收機制處理掉 //這就是閉包的作用,調用bar()函數,就會執行里面的foo函數,foo這時就會訪問到外層的變量 bar2();

因此我們可以在函數內部再創建一個函數,這樣對內部的函數來說,外層函數的變量都是可見的,然后我們就可以訪問到他的變量了。

3、閉包的優點:

  • 方便調用上下文中聲明的局部變量
  • 邏輯緊密,可以在一個函數中再創建個函數,避免了傳參的問題

4、閉包的缺點:

      因為使用閉包,可以使函數在執行完后不被銷毀,保留在內存中,如果大量使用閉包就會造成內存泄露,內存消耗很大

 

實際開發中js閉包的應用

1。在函數外使用函數內的變量 .函數作為返回值   (閉包作用:避免變量被環境污染)

function F1(){ var a = 100; return function(){ console.log(a) } } var f1 =F1(); var a = 200; f1()//100
function init(){ var name = "hello world";//name是一個被init創建的局部變量 function sayName(){//sayName是一個內部函數,閉包 alert(name);//使用了父級函數聲明的變量name } sayName(); } init();//"hello world"

 

2.函數作為參數傳遞

function F1(){ var a = 100; return function(){ console.log(a) } } var f1 =F1(); function F2(fn){ var a = 200; fn(); } F2(f1); // 100

 

3.將函數與其所操作的某些數據關聯起來,通常,你使用只有一個方法的對象的地方,都可以使用閉包

// 改變dom樣式 document.getElementById("a").onclick = setSize(12); document.getElementById("b").onclick = setSize(18); document.getElementById("c").onclick = setSize(22); function setSize(fontSize){ return function(){ document.body.style.fontSize = fontSize + 'px'; } }

 

4.用閉包模擬私有方法

//這三個公共函數是共享同一個環境的閉包。多虧 JavaScript 的詞法作用域,它們都可以訪問 privateCounter 變量和 changeBy 函數。 var makeCounter = function () { var privateCounter = 0; function changeBy(val){ privateCounter += val; }; return { increment: function(){ changeBy(1); }, decrement: function(){ changeBy(-1); }, value: function(){ return privateCounter; } } }; var Counter1 = makeCounter(); var Counter2 = makeCounter(); Counter1.increment(); console.log(Counter1.value());//1 每次調用其中一個計數器時,通過改變這個變量的值,會改變這個閉包的詞法環境。然而在一個閉包內對變量的修改,不會影響到另外一個閉包中的變量。 console.log(Counter2.value());//0 以這種方式使用閉包,提供了許多與面向對象編程相關的好處 —— 特別是數據隱藏和封裝。

資源搜索網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com

5.循環里面的閉包

怎么才能實現輸出0-5呢?

for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1000 * i); }//55555
//方法一,makeCallback函數為每一個回調創建一個新的詞法環境。 function makeCallback(i) { return function() { console.log(i) }; } for(var i=0;i<10;i++){ setTimeout(makeCallback(i),1000) }
//另一種方法使用了匿名閉包 for(var i=0;i<10;i++){ (function(i){ setTimeout(function () { console.log(i) },1000) })(i) }
//使用let聲明變量 for (let i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1000 * i); }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM