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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JS闭包的理解及常见应用场景

發布時間:2025/7/14 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS闭包的理解及常见应用场景 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JS閉包的理解及常見應用場景

一、總結

一句話總結:

閉包是指有權訪問另一個函數作用域中的變量的函數

?

1、如何從外部讀取函數內部的變量,為什么?

閉包:f2可以讀取f1中的變量,只要把f2作為返回值,就可以在f1外讀取f1內部變
原因:f1是f2的父函數,f2被賦給了一個全局變量,f2始終存在內存中,f2的存在依賴f1,因此f1也始終存在內存中,不會在調用結束后,被垃圾回收機制回收。
function f1(){var n = 123;function f2(){ //f2是一個閉包 alert(n)} return f2;}js鏈式作用域:子對象會一級一級向上尋找所有父對象的變量,反之不行。

?

?

2、js鏈式作用域?

子對象會一級一級向上尋找所有父對象的變量,反之不行。
js中函數內部可以讀取全局變量,函數外部不能讀取函數內部的局部變量。

?

?

3、js變量兩種作用域?

全局變量、局部變量(函數內):js中函數內部可以讀取全局變量,函數外部不能讀取函數內部的局部變量。

?

?

4、閉包為什么可以實現在函數外讀取到函數內的變量?

|||-begin

function f1(){var n = 123;function f2(){ //f2是一個閉包 alert(n)} return f2;}

|||-end

原因:f1是f2的父函數,f2被賦給了一個全局變量,f2始終存在內存中,f2的存在依賴f1,因此f1也始終存在內存中,不會在調用結束后,被垃圾回收機制回收。

?

?

?

二、對JS閉包的理解及常見應用場景

轉自或參考:對JS閉包的理解及常見應用場景
https://blog.csdn.net/qq_21132509/article/details/80694517

1、變量作用域

變量作用域兩種:全局變量、局部變量。js中函數內部可以讀取全局變量,函數外部不能讀取函數內部的局部變量。

2、如何從外部讀取函數內部的變量?

function f1(){var n = 123;function f2(){ //f2是一個閉包alert(n)} return f2;} js鏈式作用域:子對象會一級一級向上尋找所有父對象的變量,反之不行。 f2可以讀取f1中的變量,只要把f2作為返回值,就可以在f1外讀取f1內部變量

3、閉包概念

能夠讀取其他函數內部變量的函數。 或簡單理解為定義在一個函數內部的函數,內部函數持有外部函數內變量的引用。

4、閉包用途

1、讀取函數內部的變量 2、讓這些變量的值始終保持在內存中。不會再f1調用后被自動清除。 3、方便調用上下文的局部變量。利于代碼封裝。 原因:f1是f2的父函數,f2被賦給了一個全局變量,f2始終存在內存中,f2的存在依賴f1,因此f1也始終存在內存中,不會在調用結束后,被垃圾回收機制回收。

5、閉包理解

/*** [init description]* @return {[type]} [description]*/ function init() {var name = "Chrome"; //創建局部變量name和局部函數alertNamefunction alertName() { //alertName()是函數內部方法,是一個閉包alert(name); //使用了外部函數聲明的變量,內部函數可以訪問外部函數的變量}alertName(); } init(); //一個變量在源碼中聲明的位置作為它的作用域,同時嵌套的函數可以訪問到其外層作用域中聲明的變量/*** [outFun description]* @return {[type]} [description]*/ function outFun(){var name = "Chrome";function alertName(){alert(name);}return alertName; //alertName被外部函數作為返回值返回了,返回的是一個閉包 }var myFun = outFun(); myFun(); /* 閉包有函數+它的詞法環境;詞法環境指函數創建時可訪問的所有變量。 myFun引用了一個閉包,閉包由alertName()和閉包創建時存在的“Chrome”字符串組成。 alertName()持有了name的引用, myFunc持有了alertName()的的訪問, 因此myFunc調用時,name還是處于可以訪問的狀態。*//*** [add description]* @param {[type]} x [description]*/ function add(x){return function(y){return x + y;}; }var addFun1 = add(4); var addFun2 = add(9);console.log(addFun1(2)); //6 console.log(addFun2(2)); //11 //add接受一個參數x,返回一個函數,它的參數是y,返回x+y //add是一個函數工廠,傳入一個參數,就可以創建一個參數和其他參數求值的函數。 //addFun1和addFun2都是閉包。他們使用相同的函數定義,但詞法環境不同,addFun1中x是4,后者是5

6、閉包應用場景之setTimeout

//原生的setTimeout傳遞的第一個函數不能帶參數setTimeout(function(param){alert(param)},1000)//通過閉包可以實現傳參效果function func(param){return function(){alert(param)}}var f1 = func(1);setTimeout(f1,1000);

7、閉包應用場景之回調

<!DOCTYPE html> <html> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title></title><link rel="stylesheet" href=""> </head> <style>body{font-size: 12px;}h1{font-size: 1.5rem;}h2{font-size: 1.2rem;} </style> <body><p>哈哈哈哈哈哈</p><h1>hhhhhhhhh</h1><h2>qqqqqqqqq</h2><a href="#" id="size-12">12</a><a href="#" id="size-14">14</a><a href="#" id="size-16">16</a><script>function changeSize(size){return function(){document.body.style.fontSize = size + 'px';};}var size12 = changeSize(12);var size14 = changeSize(14);var size16 = changeSize(16);document.getElementById('size-12').onclick = size12;document.getElementById('size-14').onclick = size14;document.getElementById('size-16').onclick = size16;//我們定義行為,然后把它關聯到某個用戶事件上(點擊或者按鍵)。我們的代碼通常會作為一個回調(事件觸發時調用的函數)綁定到事件上 </script> </body> </html>

8、閉包應用場景之封裝變量

<!DOCTYPE html> <html> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>閉包模擬私有方法</title><link rel="stylesheet" href=""> </head> <body> <script>//用閉包定義能訪問私有函數和私有變量的公有函數。var counter = (function(){var privateCounter = 0; //私有變量function change(val){privateCounter += val;}return {increment:function(){ //三個閉包共享一個詞法環境change(1);},decrement:function(){change(-1);},value:function(){return privateCounter;}};})();console.log(counter.value());//0counter.increment();counter.increment();//2//共享的環境創建在一個匿名函數體內,立即執行。//環境中有一個局部變量一個局部函數,通過匿名函數返回的對象的三個公共函數訪問。</script> </body> </html>

9、閉包應用場景之為節點循環綁定click事件

<!DOCTYPE html> <html> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title></title><link rel="stylesheet" href=""> </head> <body><p id="info">123</p><p>E-mail: <input type="text" id="email" name="email"></p><p>Name: <input type="text" id="name" name="name"></p><p>Age: <input type="text" id="age" name="age"></p><script>function showContent(content){document.getElementById('info').innerHTML = content;};function setContent(){var infoArr = [{'id':'email','content':'your email address'},{'id':'name','content':'your name'},{'id':'age','content':'your age'}];for (var i = 0; i < infoArr.length; i++) {var item = infoArr[i];document.getElementById(item.id).onfocus = function(){showContent(item.content)}}}setContent()//循環中創建了三個閉包,他們使用了相同的詞法環境item,item.content是變化的變量//當onfocus執行時,item.content才確定,此時循環已經結束,三個閉包共享的item已經指向數組最后一項。/*** 解決方法1 通過函數工廠,則函數為每一個回調都創建一個新的詞法環境*/function showContent(content){document.getElementById('info').innerHTML = content;};function callBack(content){return function(){showContent(content)}};function setContent(){var infoArr = [{'id':'email','content':'your email address'},{'id':'name','content':'your name'},{'id':'age','content':'your age'}];for (var i = 0; i < infoArr.length; i++) {var item = infoArr[i];document.getElementById(item.id).onfocus = callBack(item.content)}}setContent()/*** 解決方法2 綁定事件放在立即執行函數中*/function showContent(content){document.getElementById('info').innerHTML = content;};function setContent(){var infoArr = [{'id':'email','content':'your email address'},{'id':'name','content':'your name'},{'id':'age','content':'your age'}];for (var i = 0; i < infoArr.length; i++) {(function(){var item = infoArr[i];document.getElementById(item.id).onfocus = function(){showContent(item.content)}})()//放立即執行函數,立即綁定,用每次的值綁定到事件上,而不是循環結束的值}}setContent()/*** 解決方案3 用ES6聲明,避免聲明提前,作用域只在當前塊內*/function showContent(content){document.getElementById('info').innerHTML = content;};function setContent(){var infoArr = [{'id':'email','content':'your email address'},{'id':'name','content':'your name'},{'id':'age','content':'your age'}];for (var i = 0; i < infoArr.length; i++) {let item = infoArr[i]; //限制作用域只在當前塊內document.getElementById(item.id).onfocus = function(){showContent(item.content)}}}setContent() </script> </body> </html>

?

轉載于:https://www.cnblogs.com/Renyi-Fan/p/11590231.html

總結

以上是生活随笔為你收集整理的JS闭包的理解及常见应用场景的全部內容,希望文章能夠幫你解決所遇到的問題。

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