麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > JavaScript > 正文

javascript中的閉包概念與用法實(shí)踐分析

2019-11-19 11:07:34
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文實(shí)例講述了javascript中的閉包概念與用法。分享給大家供大家參考,具體如下:

閉包的概念:閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù) (引自《javascript高級(jí)程序設(shè)計(jì)第三版》178頁(yè))。閉包的優(yōu)點(diǎn)是不會(huì)產(chǎn)生全局變量,避免變量污染問(wèn)題,但是閉包也有一個(gè)缺點(diǎn)就是閉包攜帶包含它的函數(shù)作用域會(huì)比其它函數(shù)占用更多的內(nèi)存,過(guò)度使用會(huì)導(dǎo)致內(nèi)存占用過(guò)多。

wiki上關(guān)于閉包的概念:

In programming languages, closures (also lexical closures or function closures) are techniques for implementing lexically scoped name binding in languages with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment:[1] a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.[b] A closure―unlike a plain function―allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

簡(jiǎn)單來(lái)說(shuō):閉包是一個(gè)存儲(chǔ)了函數(shù)以及與這個(gè)函數(shù)相關(guān)的環(huán)境信息的記錄。

閉包實(shí)踐一:初次體驗(yàn)閉包

function a() { var temp = 100; function b() {  console.log(++temp); } return b;}var fn = a(); // 此時(shí)fn屬于全局的函數(shù)。fn();// 101fn();// 102

在函數(shù)a的內(nèi)部return出了一個(gè)局部函數(shù)b。讓函數(shù)fn接收函數(shù)a的返回值,也就是函數(shù)b。連續(xù)執(zhí)行了兩次fn,輸出結(jié)果101,,102表示,函數(shù)fn一直引用著函數(shù)a中的局部變量temp。每次調(diào)用fn,temp都會(huì)被自增1。從此處說(shuō)明了函數(shù)a一直沒(méi)有被垃圾回收機(jī)制(GC)回收。以上代碼還可以這樣優(yōu)化:

function a() { var temp = 100; return function() {  console.log(++temp); }}var fn = a();a = null;fn();// 101fn();// 102fn = null; // 調(diào)用完畢后要,要解除對(duì)內(nèi)部匿名函數(shù)的引用,以便釋放內(nèi)存

閉包實(shí)踐二:閉包與變量

分析下面的代碼

html結(jié)構(gòu):

<ul> <li>0</li> <li>1</li> <li>2</li></ul>

javascript結(jié)構(gòu):

var ul = document.querySelector('ul');// 為了演示方便,直接用html5的apivar lis = ul.children;for(var i=0; i< lis.length; i++) { lis[i].οnclick=function(){  console.log(i); }}

當(dāng)點(diǎn)擊每個(gè)li時(shí),輸出的全都是3,在點(diǎn)擊事件之前,for循環(huán)早已經(jīng)執(zhí)行完了,i的值為3。為了防止這種情況發(fā)生,for循環(huán)還可以修改成這樣:

for(var i=0; i< lis.length; i++) { lis[i].οnclick=function(num){  return function(){   console.log(num);  } }(i)}

由于函數(shù)是按值傳遞的,所以就會(huì)將變量i的當(dāng)前值賦給num,而在函數(shù)內(nèi)部又返回了一個(gè)訪問(wèn)num的閉包。這樣每次i的值就保存下來(lái)了。值得一提的是在ECMAScript6中可以用嚴(yán)格模式下用let 來(lái)聲明i。這樣可以直接保存i,有關(guān)es6,以后再深入學(xué)習(xí),示例代碼如下:

javascript結(jié)構(gòu):

'use strict'let ul = document.querySelector('ul');let lis = ul.children;for(let i=0; i< lis.length; i++) { lis[i].οnclick=function(){   console.log(i); }}

閉包實(shí)踐三:對(duì)實(shí)踐二的深層剖析,閉包保存的是整個(gè)變量對(duì)象,而不是某個(gè)特殊的變量。(出自 《javascript高級(jí)程序設(shè)計(jì)第三版》 181頁(yè))

/* createFunctions方法返回一個(gè)函數(shù)數(shù)組 result */function createFunctions() { var result = new Array(); for(var i=0; i<10;i++) {  result[i] = function() {   return i;  } } return result;}var arr = createFunctions();// 我們拿到并輸出第一個(gè)數(shù)組元素函數(shù)的返回值var fn0 = arr[0];var varible0 = fn0();console.log(varible0); // 返回的是 10// 我們拿到并輸出第二個(gè)數(shù)組元素函數(shù)的返回值var fn1 = arr[1];var varible1 = fn1();console.log(varible1); // 返回的是 10// 可見(jiàn)閉包保存的是這個(gè)變量i對(duì)象,i的最終結(jié)果是10

我們只要對(duì)代碼稍稍?xún)?yōu)化,用自執(zhí)行函數(shù)來(lái)處理,就可以達(dá)到我們的預(yù)期了,如下:

function createFunctions() { var result = new Array(); for(var i=0; i<10;i++) {  result[i] = (function(num) {   return function(){    return num;   }  })(i) } return result;}var arr = createFunctions();// 我們拿到并輸出第一個(gè)數(shù)組元素函數(shù)的返回值var fn0 = arr[0];var varible0 = fn0();console.log(varible0); // 返回的是 0// 我們拿到并輸出最后一個(gè)數(shù)組元素函數(shù)的返回值var fn9 = arr[9];var varible9 = fn9();console.log(varible9); // 返回的是 9

閉包實(shí)踐四:閉包與this  使用不同的編程方式使用閉包,this指向不同的對(duì)象

var color = 'black';var person = { color:"yellow", getColorFun1:function(){  return function(){   return this.color;  } }, getColorFun2:function(){  var that = this;  return that.color; }}console.log(person.getColorFun1()()); // 指向了 black (備注:fn()()這種寫(xiě)法只限于非嚴(yán)格模式下)console.log(person.getColorFun2()); // 指向了yellow

說(shuō)明:當(dāng)調(diào)用到person.getColorFun1()的時(shí)候,在全局變量中生成一個(gè)函數(shù)function(){return this.color},此時(shí)的this指向是window,所以執(zhí)行到person.getColorFun1()()的時(shí)候,color為window對(duì)象下的變量color為black

而在person.getColorFun2函數(shù)中用that保存了當(dāng)前對(duì)象person,而在閉包函數(shù)里面return出去的color是person的color,所以執(zhí)行完person.getColorFun2()()的時(shí),color是yellow。

實(shí)踐四:閉包的高級(jí)應(yīng)用

示例1:實(shí)現(xiàn)函數(shù)節(jié)流 

window.onresize = throttle(function(){  var width = window.innerWidth || document.documentElement.clientWidth;  console.log(width);},300); // 調(diào)節(jié)瀏覽器窗口,在松手后的0.3s后執(zhí)行function throttle(fn,delay) {   var timer = null;   return function() {     clearTimeout(timer);     timer = setTimeout(fn,delay);   }}

示例2:實(shí)現(xiàn)封裝對(duì)象

var Person = (function(){ var haha = 0; // 這里表示可以定義一能夠使用到的參數(shù) return function(name, age){  ++ haha; // 這里表示去使用定義到的參數(shù),雖然在此處并沒(méi)有實(shí)際意義。  this.name = name;  this.age = age; };})();Person.prototype = { say : function(){  console.log(this.name + ' say hi'); }}var p1 = new Person('zhang san', 10);var p2 = new Person('li si', 20);console.log(p1.name); // zhang sanp1.say(); // zhang san say hip2.say(); // li si say hi

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具http://tools.VeVB.COm/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 久久久久久久.comav | 99影视在线视频免费观看 | 国产一级毛片高清 | 91一区二区三区久久久久国产乱 | 97伦理| 国产精品久久久久无码av | 久夜草| 国产手机在线视频 | 草久影视 | 国产一区二区三区视频在线观看 | 久久国产精品久久久久久电车 | 中文字幕极速在线观看 | 久色网站 | 国产成人精品无人区一区 | 法国性xxx精品hd专区 | 欧美综合在线观看视频 | 免费观看黄色一级视频 | 一级黄色毛片播放 | 99精品电影| 久久久99精品视频 | 国产精品免费久久久久久 | 欧美中文字幕一区二区 | 久久福利在线 | www69xxxxx| 国产v综合v亚洲欧美久久 | 久久久国产一级片 | 中国av免费观看 | 精品免费在线视频 | 羞羞视频在线免费 | 国产一级毛片不卡 | 一区二区三区视频在线播放 | 国产乱淫a∨片免费观看 | 欧美成人免费一区二区三区 | 国产亚洲精品久久 | 国产午夜免费视频 | 羞羞视频免费网站 | 深夜福利视频绿巨人视频在线观看 | 看一级毛片| 99热久草 | 国产午夜精品久久久久久免费视 | 中文字幕免费在线看 |