JS 閉包 高階函數(shù) 函數(shù)和方法的區(qū)別 AO不使用的變量

1. JS函數(shù)是一等公民(非常重要)

  • 在js中妇多,函數(shù)是非常重要的,并且是一等公民

    • 那么意味著函數(shù)的使用是非常靈活的敲街。
    • 函數(shù)可以作為另一個(gè)函數(shù)的參數(shù)扫腺,也可以作為另一個(gè)函數(shù)的返回值
  • 自己編寫高階函數(shù)

  • 使用內(nèi)置的高階函數(shù)

1.1 高階函數(shù)

如果一個(gè)函數(shù)接收另一個(gè)函數(shù)作為參數(shù)時(shí),或這個(gè)函數(shù)返回另一個(gè)函數(shù)作為返回值的函數(shù) 稱之為高階函數(shù)

1.1.1 函數(shù)作為參數(shù)使用
function calc(num1,num2,calcFn){
  console.log(calcFn(num1,num2));
}
function add(num1,num2){
  return num1+num2;
}
function sub(num1,num2){
  return num1-num2
}
function mul(num1,num2){
  return num1*num2;
}
var m=20;
var n=30;
calc(m,n,add)
calc(m,n,sub)
calc(m,n,mul)
1.1.2 函數(shù)作為返回值使用
function makeAdder(count){
  return function add(num){
    return count+num;
  }
}
var add5=makeAdder(5);
var add10=makeAdder(10);
console.log(add5(10));
console.log(add5(50));
console.log(add10(50));

1.2 函數(shù)(function)和方法(method)的區(qū)別

  • 函數(shù):當(dāng)一個(gè)function是獨(dú)立的蚕钦,不屬于任何對(duì)象的方法時(shí)亭病,則稱這個(gè)function是函數(shù)
  • 方法:如果一個(gè)function不是獨(dú)立的,是屬于某個(gè)對(duì)象嘶居,則這個(gè)function是方法
1.2.1 函數(shù)
function foo(){ //foo是一個(gè)函數(shù)

}
1.2.2 方法
var obj={
  foo:function(){ //這個(gè)foo函數(shù)是obj的一個(gè)方法

  }
}

1.3 數(shù)組一些方法的使用

var nums=[10,5,11,100,55]
// 函數(shù)function:獨(dú)立的function罪帖,稱之為是函數(shù)
// methods:方法:當(dāng)某個(gè)function屬于某個(gè)對(duì)象時(shí),我們稱這個(gè)函數(shù)是這個(gè)對(duì)象的方法

/**
 * * filter
 *  nums.filter((item,index,arr)=>boolean) //這個(gè)回調(diào)函數(shù)會(huì)回調(diào)5次邮屁,因?yàn)橛?個(gè)元素
 * item:值 index:下標(biāo) arr:當(dāng)前這個(gè)數(shù)組的引用
 */

// * 過濾 返回一個(gè)新的數(shù)組
var newNums= nums.filter(function(item){
  return item%2===0
})
console.log(newNums);
// * map 映射 [10,5,11,100,55] 返回一個(gè)新的數(shù)組
var mapNums=nums.map(function(item){
  return item*10
})
console.log(mapNums); //[ 100, 50, 110, 1000, 550 ]

// * forEach 遍歷 沒有返回值
nums.forEach(function(item){
  console.log(item);
})

// * find(返回?cái)?shù)組中元素) findIndex(返回在數(shù)組中的索引)
// let a=nums.find(function(item){
//   return item===11
// })
// console.log("a:",a);

var friends=[
  {name:"why",age:18},
  {name:"wjy",age:20},
  {name:"hyz",age:22},
  {name:"tt",age:18},
]
var item=friends.find(function(item){
  return item.name=='wjy'
})
console.log(item); //{ name: 'wjy', age: 20 }

var index=friends.findIndex(function(item){
  return item.name=='hyz'
})
console.log("index:",index); //index: 2


// * reduce 可以對(duì)原來的數(shù)組進(jìn)行統(tǒng)計(jì)或者累加  nums:[10,5,11,100,55]
// * reduce函數(shù)有兩個(gè)參數(shù)整袁,第一個(gè)參數(shù)是回調(diào)函數(shù),第二個(gè)參數(shù)是回調(diào)函數(shù)的第一個(gè)參數(shù)的初始值
// * 回調(diào)函數(shù)的參數(shù)preValue:是上一次回調(diào)函返回的值
var total=nums.reduce(function(preValue,item){
  return preValue+item
},0)
console.log(total); //181

2. JS中閉包的定義

閉包的定義佑吝,分成兩個(gè):在計(jì)算機(jī)科學(xué)中和在JavaScript中

  • 在計(jì)算機(jī)科學(xué)對(duì)閉包的定義:(維基百科)

    • 閉包(英語(yǔ):closure) 又稱詞法閉包(lexical closure)或函數(shù)閉包
    • 是支持在頭等函數(shù)的編程語(yǔ)言中坐昙,實(shí)現(xiàn)詞法綁定的一種技術(shù)
    • 閉包在實(shí)現(xiàn)上是一個(gè)結(jié)構(gòu)體,它存儲(chǔ)了一個(gè)函數(shù)和一個(gè)關(guān)聯(lián)的環(huán)境(相當(dāng)于一個(gè)符號(hào)查找表)
    • 閉包和函數(shù)最大的區(qū)別在于芋忿,當(dāng)捕捉閉包的時(shí)候炸客,它的自由變量會(huì)在捕捉時(shí)被確定,這樣即使脫離了捕捉時(shí)的上下文戈钢,它也能照常運(yùn)行痹仙。
  • 閉包的概念出現(xiàn)于60年代,最早實(shí)現(xiàn)閉包的程序是Scheme殉了,那么我們就可以理解為什么JavaScript中有閉包

    • 因?yàn)閖s的大量設(shè)計(jì)是來源于Scheme的
    • 一個(gè)函數(shù)和對(duì)其周圍狀態(tài)(Lexical Enviroment 詞法環(huán)境)的引用捆綁在一起(或者說函數(shù)被引用包圍)开仰,這樣的組合就是閉包(closure)
    • 也就是說,閉包你可以在一個(gè)內(nèi)層函數(shù)中訪問到其外層函數(shù)的作用域
    • 在js中薪铜,每當(dāng)創(chuàng)建一個(gè)函數(shù)众弓,閉包就會(huì)在函數(shù)創(chuàng)建的同時(shí)被創(chuàng)建出來
  • codewhy老師的總結(jié)

    • 一個(gè)普通的函數(shù)function,如果它可以訪問外層作用域的變量痕囱,那么它就是閉包
      • 從廣義上來講田轧,javascript函數(shù)都是閉包
      • 從狹義上來講暴匠,javascript中的一個(gè)函數(shù)鞍恢,如果訪問了外層作用域的變量,那么它就是一個(gè)閉包每窖。

2.1 代碼示例解析

function foo(){
  var name="foo";
  function bar(){
    console.log(name);
  }
  return bar;
}
var fn=foo();
fn()

// 閉包包括兩個(gè)部分:  函數(shù)+可訪問的自由變量
16.png
  • 在這里原本應(yīng)該銷毀的foo的AO對(duì)象帮掉,但是因?yàn)閎ar函數(shù)在引用其name,所以并沒有銷毀

3. 閉包的內(nèi)存泄漏

本來該被銷毀的對(duì)象窒典,卻一直沒有被銷毀蟆炊,會(huì)造成內(nèi)存泄漏。

  • 從根對(duì)象開始瀑志,能夠被訪問的對(duì)象不會(huì)被銷毀
function foo(){
  var name="foo";
  var age=18;
  function bar(){
    console.log(name);
  }
  return bar;
}
let fn=foo()
fn()
17.png
  • 例如上面的AO(0X1002)涩搓,一直未被銷毀污秆,但其實(shí)bar()函數(shù)只執(zhí)行了一次,應(yīng)當(dāng)被銷毀
18.png
  • 因?yàn)楦鶎?duì)象可到達(dá)bar昧甘、bar又可到達(dá)foo的AO
    • 因?yàn)镚C采用的是清除標(biāo)記良拼,只要能從根對(duì)象可到達(dá)的所有對(duì)象不會(huì)被銷毀,不可到達(dá)的對(duì)象會(huì)被銷毀

那怎么解決以上的內(nèi)存泄漏呢充边?

其實(shí)只要fn調(diào)用完后庸推,并設(shè)置為null,這樣從根對(duì)象就不可到達(dá)bar了浇冰,所以最后bar和foo的AO都被銷毀了

4.AO不使用的屬性

我們來探究一個(gè)問題贬媒,就是AO不會(huì)被銷毀時(shí),是否里面的所有屬性都不會(huì)被銷毀肘习?

下面這段代碼中name屬于閉包的父級(jí)作用域中的變量:

我們知道形成閉包之后age一定不會(huì)被銷毀际乘,那么name是否被銷毀呢?

  • 這里我使用了斷點(diǎn)漂佩,我們可以在瀏覽器上查看結(jié)果:
19.png

5.總結(jié)

閉包.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蚓庭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子仅仆,更是在濱河造成了極大的恐慌器赞,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墓拜,死亡現(xiàn)場(chǎng)離奇詭異港柜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)咳榜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門夏醉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涌韩,你說我怎么就攤上這事畔柔。” “怎么了臣樱?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵靶擦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我雇毫,道長(zhǎng)玄捕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任棚放,我火速辦了婚禮枚粘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘飘蚯。我一直安慰自己馍迄,他們只是感情好福也,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著攀圈,像睡著了一般拟杉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上量承,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天搬设,我揣著相機(jī)與錄音,去河邊找鬼撕捍。 笑死拿穴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的忧风。 我是一名探鬼主播默色,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼狮腿!你這毒婦竟也來了腿宰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤缘厢,失蹤者是張志新(化名)和其女友劉穎吃度,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贴硫,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椿每,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了英遭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片间护。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挖诸,靈堂內(nèi)的尸體忽然破棺而出汁尺,到底是詐尸還是另有隱情,我是刑警寧澤多律,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布痴突,位于F島的核電站,受9級(jí)特大地震影響菱涤,放射性物質(zhì)發(fā)生泄漏苞也。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一粘秆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧收毫,春花似錦攻走、人聲如沸殷勘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)玲销。三九已至,卻和暖如春摘符,著一層夾襖步出監(jiān)牢的瞬間贤斜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工逛裤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘩绒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓带族,卻偏偏與公主長(zhǎng)得像锁荔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蝙砌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容