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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Javascript的闭包及其使用技巧实例

發(fā)布時(shí)間:2025/4/16 java 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Javascript的闭包及其使用技巧实例 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Javascript的閉包及其使用技巧實(shí)例

一、閉包的基本概念

閉包(Closure)是一個(gè)引用了自由變量的函數(shù),記錄了該函數(shù)在定義時(shí)的scope chain。又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures).

閉包的基本規(guī)則:

* 函數(shù)執(zhí)行是基于函數(shù)定義時(shí)的scope, 而不是 函數(shù)運(yùn)行時(shí)的scope

(定義時(shí)的Scope: 在定義這個(gè)函數(shù)的時(shí)候的scope chain)

?

為此, JS的function對(duì)象的內(nèi)部狀態(tài),不僅包括函數(shù)代碼本身, 而且包括了一個(gè)引用,指向函數(shù)定義時(shí)的scope Chain,

后者,用于提供函數(shù)中變量的值, 這種把代碼及其所需要的scope組合到一起, 就是 閉包,closure。它是JS許多實(shí)用技巧的技術(shù)基礎(chǔ)。

?

二、閉包的應(yīng)用實(shí)例?

示例1:

var who = "global scope"; // 全局變量who

function checkscope() {??

??? var who = "local scope"; // 局部變量who

??? function f() { return who; } // 嵌套函數(shù),

??? return f();

}

checkscope(); ? ? ? ? ? ? ? ? ?// => "local scope"

?

f函數(shù)在定義的時(shí)候, scope chain中有局部變量who和全局變量who, 按照局部變量優(yōu)先于全局變量的原則,

? ?函數(shù)中的who的應(yīng)該局部變量這的who,其值是 “l(fā)ocal scope”。

這就是函數(shù)的定義時(shí)Scope。根據(jù)Clouse的特性,JS會(huì)記錄這些信息,?不論這個(gè)函數(shù)f在什么地方執(zhí)行, who的值都是這個(gè)“l(fā)ocal scope”

?

示例2:執(zhí)行的地方變了, 但是函數(shù)定義時(shí)的scope未變

var who = "global scope"; // A global variable

function checkscope() {

var who = "local scope"; // A local variable

??? function f() { return who; } // Return the value in scope here

??? return f;

}

checkscope()() // => "local scope", 雖然,在這個(gè)時(shí)候“運(yùn)行時(shí)的scope”中的who已經(jīng)是全局的了。

?

實(shí)例3: 定義一個(gè)函數(shù), 每調(diào)用一次, 獲取一個(gè)唯一的整數(shù),而且從0開始遞增,每次+1。

var uniqueInteger = (function() { // 定義并執(zhí)行1個(gè)外層函數(shù)。

????????????? var counter = 0; // 根據(jù)“定義時(shí)的scope”原則, 這個(gè)變量事實(shí)上成了下面函數(shù)的私有變量, 雖然它在函數(shù)體外,

????????????? ??????????????????? 當(dāng)外層函數(shù)返回的時(shí)候, 此變量只能被下面的嵌套函數(shù)存取,

????????????? return function() { return counter++; }; // 定義一個(gè)函數(shù),稱作嵌套函數(shù),被輸出給uniqueInteger,在外面使用, 不是在外層函數(shù)內(nèi)使用。

}());

?

uniqueInteger();? // 0

uniqueInteger();? // 1

uniqueInteger();? // 2

uniqueInteger();? // 3

?

實(shí)例4: 帶有reset的計(jì)數(shù)器

function Counter() { // 定義并執(zhí)行1個(gè)外層函數(shù)。

????????????? var n = 0; // 根據(jù)“定義時(shí)的scope”原則, 這個(gè)變量事實(shí)上成了下面2個(gè)嵌套函數(shù)的私有變量, 雖然它在函數(shù)體外,

????????????? ??????????????????? 當(dāng)外層函數(shù)返回的時(shí)候, 此變量只能被下面的嵌套函數(shù)存取,

????????????? return {? // 定義2個(gè)嵌套函數(shù),并組合成1個(gè)對(duì)象輸出, 供外面使用;

????????????? ????????? // 這兩個(gè)嵌套函數(shù), 都可以存取外層函數(shù)中的局部變量n

????????????? ? count: function() { return n++; }; 。

????????????? ? reset: function() { n = 0; }

????????????? }

};

?

var counter1 = Counter(),? // 每一次調(diào)用 外層函數(shù)Counter(),都創(chuàng)建1個(gè)新的scope chain和1個(gè)新的私有變量n,互相不影響

??? counter2 = Counter();

?

counter1.count();? // 0

counter1.count();? // 1

counter1.count();? // 2

counter2.count();? // 0

counter2.count();? // 1

counter2.count();? // 2

?

counter1.reset();

counter1.count();? // 0

counter1.count();? // 1

counter2.count();? // 3

counter2.count();? // 4

?

實(shí)例5: 與Ajax調(diào)用配合使用, 顯示加載的過程和結(jié)果

<div></div>

<script src="jquery.js"></script>

<script>

??? var elem = jQuery("div");

??? elem.html("Loading...");

??? jQuery.ajax({

??????? url: "test.html",

??????? success: function(html){? //嵌入函數(shù), 直接使用外層函數(shù)中的elem, 暴露給Ajax作為callback使用

??????????? assert( elem, "The element to append to, via a closure." );

??????????? elem.html( html );

??????? }

??? });

</script>

?

實(shí)例6: 與timer配合使用, 顯示動(dòng)畫

<div id="box" style="position:absolute;">Box!</div>

<script>

var elem = document.getElementById("box");

var count = 0;

var timer = setInterval(function(){ //嵌入函數(shù), 直接使用外層函數(shù)中的elem和count, 暴露給Timer作為callback使用

??? if ( count < 100 ) {

??????? elem.style.left = count + "px";

??????? count++;

??? } else {

??????? clearInterval( timer );

??? }

}, 10);

</script>

?

進(jìn)階: ?JS 引擎內(nèi)部是如何實(shí)現(xiàn)Scope Chain和Clouse的?

Scope Chain是一個(gè)list, 不是stack,

當(dāng)執(zhí)行function的時(shí)候, 建立1個(gè)新scope object,來存儲(chǔ)此函數(shù)中的局部變量,并且把這個(gè)object加入到scope chain中,

當(dāng)推出function的時(shí)候, 從scope chain中,刪除這個(gè)object。

?

如果沒有嵌套的函數(shù), 則此object再無引用, 所以它會(huì)被 當(dāng)作垃圾收集

如果有嵌套的函數(shù), 則每一個(gè)嵌套函數(shù)都引用scope chain, 而scope chain引用此object,

** 如果這些嵌套函數(shù),只限于在其外層函數(shù)里面使用, 則 這些嵌套函數(shù)及此object仍然可以被正常地垃圾收集。

** 如果這些嵌套函數(shù) 被用于外層函數(shù)之外的更多地方, 則這些嵌套函數(shù)及此object不能正常地垃圾收集, 從而可能導(dǎo)致造成內(nèi)存泄露,

轉(zhuǎn)載于:https://www.cnblogs.com/GameEngine/p/6427232.html

總結(jié)

以上是生活随笔為你收集整理的Javascript的闭包及其使用技巧实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。