成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript基礎(chǔ)系列---閉包及其應(yīng)用

leoperfect / 3113人閱讀

摘要:所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。所以本文中將以維基百科中的定義為準(zhǔn)即在計算機(jī)科學(xué)中,閉包,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。

閉包(closure)是JavaScript中一個“神秘”的概念,許多人都對它難以理解,我也一直處于似懂非懂的狀態(tài),前幾天深入了解了一下執(zhí)行環(huán)境以及作用域鏈,可戳查看詳情,而閉包與作用域及作用域鏈的關(guān)系密不可分,所以就再深入去理解了一番。

詞法作用域Lexical Scope

首先我們來理解一下作用域的概念:

通常來說,一段程序代碼中所用到的標(biāo)識符并不總是有效/可用的,而限定這個標(biāo)識符的可用性的代碼范圍就是這個標(biāo)識符的作用域

作用域有詞法作用域與動態(tài)作用域之分,詞法作用域也可稱為靜態(tài)作用域,這樣與動態(tài)作用域看起來更對應(yīng)。

詞法作用域在詞法分析階段就確定了作用域,之后不會再改變;也就是說詞法作用域是由你把代碼寫在哪里來決定的,與之后的運行情況無關(guān)

動態(tài)作用域在運行時根據(jù)程序的流程信息來動態(tài)確定作用域;也就是說動態(tài)作用域與運行情況有關(guān)

大部分編程語言都是基于詞法作用域,其中包括JavaScript

下面我們使用代碼來說明兩者的區(qū)別(此處僅僅使用JavaScript來說明兩種情況,實際上JavaScript只基于詞法作用域)

var cc = 6;

function foo() {
  console.log(cc); // 會輸出6還是66?
}

function bar() {
  var cc = 66;
  foo();
}

bar();

如果是詞法作用域:會輸出6,詞法作用域在寫代碼時就靜態(tài)確定了,也就是定義foo函數(shù)的時候就確定了,foo函數(shù)的內(nèi)部要訪問變量cc,由于foo的內(nèi)部作用域中沒有cc變量,所以會根據(jù)作用域鏈訪問到全局中的cc變量;這與在何處調(diào)用foo函數(shù)無關(guān)。

如果是動態(tài)作用域:會輸出66,動態(tài)作用域要根據(jù)代碼的運行情況來確定,它關(guān)心foo函數(shù)在何處被調(diào)用,而不關(guān)心它定義在哪里;foo函數(shù)的內(nèi)部要訪問變量cc,而foo的內(nèi)部作用域中沒有cc變量時,會順著調(diào)用棧在調(diào)用 foo() 的地方查找變量cc,此處是在bar函數(shù)中調(diào)用的,所以引擎會在bar的內(nèi)部作用域中查找cc變量,這個cc變量的值為66

詞法作用域鏈Lexical Scope Chain
var cc = 1;

function foo() {
  var dd = 2;
  console.log(cc);//1
  console.log(dd);//2
}

foo();
console.log(dd); //ReferenceError: dd is not defined

上面這一段代碼中,有全局變量cc以及局部變量dd,在foo函數(shù)內(nèi)部可以直接訪問全局變量cc,而在foo函數(shù)外部無法讀取foo函數(shù)內(nèi)的局部變量dd
這種結(jié)果的產(chǎn)生源于JavaScript的作用域鏈,也正是因為這個作用域鏈才有了生成閉包的可能。
作用域鏈這一部分在另一篇文章中有詳細(xì)介紹,可戳JavaScript基礎(chǔ)系列---執(zhí)行環(huán)境與作用域鏈,看完可以幫助更好的理解下文

什么是閉包?

關(guān)于閉包沒有一個官方的定義,不同的書籍解讀可能有些不同

在《JavaScript權(quán)威指南》中:

是指函數(shù)變量可以被隱藏于作用域鏈之內(nèi),因此看起來是函數(shù)將變量“包裹”了起來

在《JavaScript高級程序設(shè)計》中:

閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)

在《你不知道的JavaScript--上卷》中:

當(dāng)函數(shù)可以記住并訪問所在的詞法作用域時,就產(chǎn)生了閉包,即使函數(shù)是在當(dāng)前詞法作用
域之外執(zhí)行

在維基百科的定義:

在計算機(jī)科學(xué)中,閉包(Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。閉包在運行時可以有多個實例,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實例。

其中自由變量指:

在函數(shù)中使用的,但既不是函數(shù)參數(shù)也不是函數(shù)的局部變量的變量

一開始我也一直糾結(jié)于閉包的定義,想確切的知道閉包是什么,但是由于沒有官方的定義,難以確定。所以本文中將以維基百科中的定義為準(zhǔn)即:

在計算機(jī)科學(xué)中,閉包(Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。
閉包的創(chuàng)建

根據(jù)閉包的定義我們可以看出,閉包的產(chǎn)生條件是函數(shù)以及該函數(shù)引用了自由變量,二者缺一不可。

這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外這一描述是閉包的特性,使用閉包后能觀察到的一種現(xiàn)象,而不是閉包產(chǎn)生的條件。所以之前看到有些人說,需要將一個函數(shù)的內(nèi)部函數(shù)返回才能算閉包的言論我覺得應(yīng)該是不正確的,這應(yīng)該是在使用閉包。

常說的閉包會導(dǎo)致性能問題,也是因為這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外這一閉包特性,按理來說,在函數(shù) 執(zhí)行后,函數(shù)的整個內(nèi)部作用域通常都會被銷毀,因為我們知道引擎有垃
圾回收器用來釋放不再使用的內(nèi)存空間,但是閉包可以阻止這件事的發(fā)生,從而可能導(dǎo)致內(nèi)存中保存大量的變量,從而消耗大量內(nèi)存產(chǎn)生網(wǎng)頁性能問題。(注意是可以,可能而非一定)

下面我們直接來看幾個栗子:
1.如果考慮全局對象,那么引用了全局變量的函數(shù)可以看做創(chuàng)建了閉包,因為全局變量相對于該函數(shù)來說是自由變量

var a = 1;
function fa() {
    console.log(a);
}
fa();

此處,函數(shù)fa引用了自由變量a,fa創(chuàng)建了閉包

2.更常見的是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)

function outer(){
    var b = 2;
    function inner(){
        console.log(b);
    }
    inner();
}
outer();

此處,函數(shù)inner引用了自由變量binner創(chuàng)建了閉包。
根據(jù)JavaScript基礎(chǔ)系列---執(zhí)行環(huán)境與作用域鏈中的描述我們可以知道,調(diào)用outer()后,會進(jìn)入Function Execution Context outer的創(chuàng)建階段:

創(chuàng)建作用域鏈,outer函數(shù)的[[Scopes]]屬性被加入其中

創(chuàng)建outer函數(shù)的活動對象AO(作為該Function Execution Context的變量對象VO),并將創(chuàng)建的這個活動對象AO加到作用域鏈的最前端

確定this的值

此時Function Execution Context outer可表示為:

outerEC = {
    scopeChain: {
        pointer to outerEC.VO,
        outer.[[Scopes]]
    },
    VO: {
        arguments: {
            length: 0
        },
        b: 2,
        inner: pointer to function inner(),
    },
    this: { ... }
}

接著進(jìn)入Function Execution Context outer的執(zhí)行階段:

當(dāng)遇到inner函數(shù)定義語句,進(jìn)入inner函數(shù)的定義階段,inner[[Scopes]]屬性被確定

inner.[[Scopes]] = {
    pointer to outerEC.VO,
    pointer to globalEC.VO
}

遇到inner()調(diào)用語句,進(jìn)入inner函數(shù)調(diào)用階段,此時進(jìn)入Function Execution Context inner的創(chuàng)建階段:

創(chuàng)建作用域鏈,inner函數(shù)的[[Scopes]]屬性被加入其中

創(chuàng)建inner函數(shù)的活動對象AO(作為該Function Execution Context的變量對象VO),并將創(chuàng)建的這個活動對象AO加到作用域鏈的最前端

確定this的值

此時Function Execution Context inner可表示為:

innerEC = {
    scopeChain: {
        pointer to innerEC.VO,
        inner.[[Scopes]]
    },
    VO: {
        arguments: {
            length: 0
        },
    },
    this: { ... }
}

接著進(jìn)入Function Execution Context inner的執(zhí)行階段:遇到打印語句console.log(b);,通過inner.[[Scopes]]訪問到變量b=2

至此,函數(shù)inner執(zhí)行完畢,Function Execution Context inner的作用域鏈及變量對象被銷毀

然后函數(shù)outer也執(zhí)行完畢,Function Execution Context outer的作用域鏈及變量對象被銷毀。

這種情況下,函數(shù)執(zhí)行完畢后該銷毀的都被銷毀了,沒有占用內(nèi)存,所以這種情況下閉包是不會對性能有占用內(nèi)存方面的影響的。

3.最常被討論的閉包

栗子1

function fa(){
    var n = 666;
    function fb(){
        console.log(n);
    }
    return fb;
}
var getN = fa();
getN();

此處,函數(shù)fb引用了自由變量n,fb創(chuàng)建了閉包,并且fb被傳遞到了創(chuàng)造它的環(huán)境以外(所在的詞法作用域以外)。

這段代碼的執(zhí)行情況與上面類似,鑒于篇幅就不一一展開詳細(xì)描述了,大家可以自己推一遍;現(xiàn)在主要描述一下不同之處,在fa函數(shù)的最后,fa函數(shù)將它的內(nèi)部函數(shù)fb返回了,按理說返回之后fa函數(shù)就執(zhí)行完畢了,其作用域鏈和活動對象應(yīng)該被銷毀,但是閉包fb阻止了這件事的發(fā)生:

函數(shù)fb定義之后其[[Scopes]]屬性被確定,這個屬性至此之后一直保持不變,直至函數(shù)fb被銷毀,可以表示為

fb.[[Scopes]] = {
    pointer to fa.VO,
    pointer to globalEC.VO
}

函數(shù)fa執(zhí)行完畢后,將其返回值--fb函數(shù)賦給了全局變量getN,這樣一來由于getN是全局變量,而全局變量是在Global Execution Context中的,需要等到應(yīng)用程序退出后 —— 如關(guān)閉網(wǎng)頁或瀏覽器 —— 才會被銷毀,那么也就意味著fb函數(shù)也要到這時才會被銷毀

fb函數(shù)的[[Scopes]]屬性中引用了fa函數(shù)的變量(活動)對象,意味著fa函數(shù)的變量(活動)對象可能隨時還需要用到,這樣一來fa函數(shù)執(zhí)行完畢之后,只有Function Execution Context fa的作用域鏈會被銷毀,而變量(活動)對象仍然會在內(nèi)存中

這樣遇到getN()語句時,實際上就是調(diào)用fb函數(shù),于是順著fb的作用域鏈找到變量n并打印出來

這里我們分析一下,變量n是閉包fb引用的自由變量,創(chuàng)造這個n這個自由變量的是函數(shù)fa,此時fa執(zhí)行完畢之后,自由變量n仍然可以訪問到(仍然存在),并且在fa函數(shù)外也能訪問到(離開fa之后)。這一點也就正對應(yīng)于這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外

除了將內(nèi)部函數(shù)return這種方式之外,還有其他方式可以使用閉包,這些方式的共同之處是:將內(nèi)部函數(shù)傳遞到創(chuàng)造它的環(huán)境以外(所在的詞法作用域以外),之后無論在何處執(zhí)行這個函數(shù)就都會使用閉包。

栗子2

function foo() {
    var a = 2;
    function baz() {
        console.log( a ); // 2
    }
    bar( baz );
}
function bar(fn) {
    fn();
}
foo();

這個栗子中,是通過函數(shù)傳參來將內(nèi)部函數(shù)baz傳遞到它所在的詞法作用域以外的

栗子3

var fn;
function foo() {
    var a = 2;
    function baz() {
        console.log( a );
    }
    fn = baz; // 將baz 賦給全局變量
}
foo();
fn(); // 2

這個栗子中,是通過賦值給全局變量fn來將內(nèi)部函數(shù)baz傳遞到它所在的詞法作用域以外的。

在栗子1和栗子3這種情況下呢,閉包使得它自己的變量對象以及包含它的函數(shù)的變量對象都存在于內(nèi)存中,如果濫用就很有可能導(dǎo)致性能問題。所以在不需要閉包后,最好主動解除對閉包的引用,告訴垃圾回收機(jī)制將其清除,比如在上面這些例子中進(jìn)行getN = null;fn = null的操作。

4.經(jīng)常用但可能并沒有意識到它就是閉包的閉包

栗子1

function wait(msg) {
    setTimeout( function timer() {
        console.log( msg );
    }, 1000 );
}
wait( "Hello, closure!" );

上面的代碼其實可以理解為下面這樣:

function wait(msg) {
    function timer(){
        console.log( msg );
    }
    setTimeout( timer, 1000 );
}
wait( "Hello, closure!" );

內(nèi)部函數(shù)timer引用了自由變量msg,timer創(chuàng)建了閉包,然后將timer傳遞給setTimeout(..),也就是將內(nèi)部函數(shù)timer傳遞到了所在的詞法作用域以外。

當(dāng)wait(..) 執(zhí)行1000 毫秒后,wait的變量對象并不會消失,timer函數(shù)可以訪問變量msg,只有當(dāng)setTimeout(..)執(zhí)行完畢后,wait的變量對象才會被銷毀。

栗子2

function bindName(name, selector) {
    $( selector ).click( function showName() {
        console.log( "This name is: " + name );
    } );
}
bindName( "Closure", "#closure" );

上面的代碼其實可以理解為下面這樣:

function bindName(name, selector) {
    function showName(){
        console.log( "This name is: " + name );
    }
    $( selector ).click( showName );
}
bindName( "Closure", "#closure" );

內(nèi)部函數(shù)showName引用了自由變量nameshowName創(chuàng)建了閉包,然后將showName傳遞給click事件作為回調(diào)函數(shù),也就是將內(nèi)部函數(shù)showName傳遞到了所在的詞法作用域以外。
當(dāng)bindName(..)執(zhí)行之后,bindName的變量對象并不會消失,每當(dāng)這個click事件觸發(fā)的時候showName函數(shù)可以訪問變量name

5.同一個調(diào)用函數(shù)創(chuàng)建的閉包共享引用的自由變量

function change() {
    var num = 10;
        return{
        up:function() {
            num++;
            console.log(num);
        },
        down:function(){
            num--;
            console.log(num);
        }
    }
}
var opt = change();
opt.up();//11
opt.up();//12
opt.down();//11
opt.down();//10

opt.upopt.down共享變量num的引用,它們操作的是同一個變量num,因為調(diào)用一次change只會創(chuàng)建并進(jìn)入一個Function Execution Context change,通過閉包留在內(nèi)存中的變量對象只有一個。

6.不同調(diào)用函數(shù)創(chuàng)建的閉包互不影響

function change() {
   var num = 10;
       return{
       up:function() {
           num++;
           console.log(num);
       },
       down:function(){
           num--;
           console.log(num);
       }
   }
}
var opt1 = change();
var opt2 = change();
opt1.up();//11
opt1.up();//12
opt2.down();//9
opt2.down();//8

change函數(shù)被調(diào)用了兩次,分別賦值給opt1opt2,此時opt1.up,opt2.up以及opt1.down,opt2.down是互不影響的,因為每調(diào)用一次就會創(chuàng)建并進(jìn)入一個新的Function Execution Context change,也就會有新的變量對象,所以不同調(diào)用函數(shù)通過閉包留在內(nèi)存中的變量對象是獨立的,互不影響的。

7.關(guān)于上面提到的兩點,有一個談到閉包就被拿出來的例子:

for(var i=1;i<6;i++){
    setTimeout(function(){
        console.log(i);
    },i*1000);
}

上述例子乍一看會覺得輸出的結(jié)果是:每隔1s分別打印出1,2,3,4,5;然而實際上的結(jié)果是:每隔1s分別打印出6,6,6,6,6。

那么是為什么會這樣呢?下面就來解析一下(ES6之前沒有let命令,不存在真正的塊級作用域):

變量i此處為全局變量,我們考慮全局變量,那么傳遞給setTimeout(...)的這個匿名函數(shù)創(chuàng)建了閉包,因為它引用了變量i;雖然循環(huán)中的五個函數(shù)是在各次迭代中分別定義的,但是它們引用的是全局變量i,這個i只有一個,所以它們引用的是同一個變量(如果在此處將全局對象想象成一個僅調(diào)用了一次的函數(shù)的返回值,那么這個現(xiàn)象便可以對應(yīng)于 ———— 同一個調(diào)用函數(shù)創(chuàng)建的閉包共享引用的自由變量)

setTimeout()的回調(diào)會在循環(huán)結(jié)束時才執(zhí)行,即使每個迭代中執(zhí)行的是setTimeout(.., 0),而循環(huán)結(jié)束時全局變量i的值已經(jīng)變成6了,所以最后輸出的結(jié)果是每隔1s分別打印出6,6,6,6,6。

要解決上面這個問題,最簡單的方式當(dāng)然是ES6中喜人的let命令了,僅需將var改為let即可,for 循環(huán)頭部的let 聲明會有一個特殊的行為。這個行為指出變量在循環(huán)過程中不止被聲明一次,每次迭代都會聲明。隨后的每個迭代都會使用上一個迭代結(jié)束時的值來初始化這個變量。

拋開喜人的ES6,又該怎么解決呢,既然上面的問題是由于共享同一個變量而導(dǎo)致的,那么我想辦法讓它不共享,而是每個函數(shù)引用一個不同的變量不就好了。上面提到了 ———— 不同調(diào)用函數(shù)創(chuàng)建的閉包互不影響,我們就要利用這個來解決這個問題:

for(var i=1;i<6;i++){
   waitShow(i);
}

function waitShow(j){
    setTimeout(function(){
        console.log(j);
    },j*1000);
}

我們將循環(huán)內(nèi)的代碼改成了一個函數(shù)調(diào)用語句waitShow(i),而waitShow函數(shù)的內(nèi)容就是之前循環(huán)體內(nèi)的內(nèi)容;waitShow內(nèi)部傳遞給setTimeout(...)的這個匿名函數(shù)仍然創(chuàng)建了閉包,只不過這次引用的是waitShow的參數(shù)j。

現(xiàn)在每迭代一次,便會調(diào)用waitShow一次,而我們從上文中已經(jīng)知道不同調(diào)用函數(shù)創(chuàng)建的閉包互不影響,所以就可以解決問題了!當(dāng)然,這還不是你常見的樣子,現(xiàn)在我們稍稍改動一下,就變成非常常見的IIFE形式了:

for(var i=1;i<6;i++){
   (function(j){
        setTimeout(function(){
            console.log(j);
        },j*1000);
   })(i)
}

balabala說了這么多,其實我們平常寫代碼的時候經(jīng)常無意識的就創(chuàng)建了閉包,但是創(chuàng)建了我們不一定會去使用閉包,而閉包的“威力”需要通過使用才能看得到。

閉包的應(yīng)用

閉包到底有什么用呢?我覺得總結(jié)成一句話就是:

“凍結(jié)”閉包的包含函數(shù)調(diào)用時的變量對象(使其以當(dāng)前值留在內(nèi)存中),并只有通過該閉包才能“解凍”(訪問/操作留在內(nèi)存中的變量對象)

粗看可能不是很能理解,下面我們結(jié)合具體的應(yīng)用場景來理解:

恩。。。首先我們來看一個老朋友,剛剛見過面的老朋友

for(var i=1;i<6;i++){
   (function(j){
        setTimeout(function(){
            console.log(j);
        },j*1000);
   })(i)
}

在這個栗子中,每個IIFE自調(diào)用時,其內(nèi)部創(chuàng)建的閉包將其當(dāng)時的變量對象“凍結(jié)”了,并且通過將這個閉包作為setTimeout的參數(shù)傳遞到IIFE作用域以外;所以第一次循環(huán)“凍結(jié)”的j的值是1,第二次循環(huán)“凍結(jié)”的j的值是2......當(dāng)循環(huán)結(jié)束后,延遲時間到了后,setTimeout的回調(diào)執(zhí)行(即使用閉包),“解凍”了之前“凍結(jié)”的變量j,然后打印出來。

既然提到setTimeout,那再來看看另外一個應(yīng)用,我們知道在標(biāo)準(zhǔn)的setTimeout是可以向延遲函數(shù)傳遞額外的參數(shù)的,形式是這樣:setTimeout(function[, delay, param1, param2, ...]),,一旦定時器到期,它們會作為參數(shù)傳遞給function。但是萬惡的IE搞事情,在IE9及其之前的版本中是不支持傳遞額外參數(shù)的。那有時候我們確實有需要傳參數(shù),怎么辦呢。通常的解決方法有下面這些:

function fullName( givenName ){
    let familyName = "Swift";
    console.log("The fullName is: " + givenName + " " + familyName);
}
setTimeout(fullName,1000,"Taylor Alison");

使用一個匿名函數(shù)包裹

setTimeout(function(){
    fullName("Taylor Alison");
},1000);

使用bindES5引入)

setTimeout(fullName.bind(undefined,"Taylor Alison"),1000);

polyfill

使用閉包

function fullName( givenName ){
    let familyName = "Swift";
    return function(){
        console.log("The fullName is: " + givenName + " " + familyName);
    }
    
}
let showFullName = fullName("Taylor Alison");
setTimeout(showFullName,1000);

fullName內(nèi)的匿名函數(shù)創(chuàng)建了閉包,并作為返回值返回,調(diào)用fullName()后返回值賦給變量showFullName,此時fullName的變量對象被“凍結(jié)”,只能通過showFullName才能“解凍”,定時器到期后,showFullName被調(diào)用,通過之前被“凍結(jié)”的變量對象訪問到givenNamefamilyName。

待續(xù)(有時間補(bǔ)上)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95533.html

相關(guān)文章

  • JS 閉包(closure)

    摘要:對數(shù)組函數(shù)而言,相當(dāng)于產(chǎn)生了個閉包。關(guān)于對象在閉包中使用對象也會導(dǎo)致一些問題。不過,匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其對象通常指向。由于聲明函數(shù)時與聲明函數(shù)時的值是不同的,因此閉包與閉包貌似將會表示各自不同的值。 這幾天看到閉包一章,從工具書到各路大神博客,都各自有著不同的理解,以下我將選擇性的抄(咳咳,當(dāng)然還是會附上自己理解的)一些大神們對閉包的原理及其使用文章,當(dāng)作是自己初步理解...

    nihao 評論0 收藏0
  • 【重溫基礎(chǔ)】22.內(nèi)存管理

    摘要:內(nèi)存泄露內(nèi)存泄露概念在計算機(jī)科學(xué)中,內(nèi)存泄漏指由于疏忽或錯誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。判斷內(nèi)存泄漏,以字段為準(zhǔn)。 本文是 重溫基礎(chǔ) 系列文章的第二十二篇。 今日感受:優(yōu)化學(xué)習(xí)方法。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1-14篇 【重溫基礎(chǔ)】15.JS對象介紹 【重溫基礎(chǔ)】16.JSON對象介紹 【重溫基礎(chǔ)】1...

    Pandaaa 評論0 收藏0
  • 前端基礎(chǔ)

    摘要:談起閉包,它可是兩個核心技術(shù)之一異步基于打造前端持續(xù)集成開發(fā)環(huán)境本文將以一個標(biāo)準(zhǔn)的項目為例,完全拋棄傳統(tǒng)的前端項目開發(fā)部署方式,基于容器技術(shù)打造一個精簡的前端持續(xù)集成的開發(fā)環(huán)境。 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果讀完本文還不懂,可以揍我。 不論你是javascript新手還是老鳥,不論是面試求職,還是日...

    graf 評論0 收藏0
  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評論0 收藏0
  • JavaScript 工作原理之三-內(nèi)存管理及如何處理 4 類常見的內(nèi)存泄漏問題(譯)

    摘要:這是因為我們訪問了數(shù)組中不存在的數(shù)組元素它超過了最后一個實際分配到內(nèi)存的數(shù)組元素字節(jié),并且有可能會讀取或者覆寫的位。包含個元素的新數(shù)組由和數(shù)組元素所組成中的內(nèi)存使用中使用分配的內(nèi)存主要指的是內(nèi)存讀寫。 原文請查閱這里,本文有進(jìn)行刪減,文后增了些經(jīng)驗總結(jié)。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第三章。 我們將會討論日常使用中另一個被開發(fā)...

    weknow619 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<