摘要:當(dāng)我們把函數(shù)傳遞給函數(shù),并且讓能夠在某一時(shí)刻執(zhí)行,這種情況我們稱函數(shù)是回調(diào)函數(shù),簡(jiǎn)稱回調(diào)。返回函數(shù)剛剛在回調(diào)函數(shù)部分,說的是函數(shù)作為另一個(gè)函數(shù)的參數(shù)傳遞,接下來說說函數(shù)作為另一邊函數(shù)的結(jié)果返回。
寫在前面
由于詞語匱乏,本文繼續(xù)沿用"深入解析xxx"這個(gè)俗套的命名,但是是真的很深入(你要信我啊)。如果本文對(duì)你有用,歡迎收藏,如果喜歡我的文章,歡迎點(diǎn)贊和關(guān)注專欄。
函數(shù)可以說是js的基礎(chǔ),無處不在,功能又十分強(qiáng)大,本文將簡(jiǎn)單介紹函數(shù)的特點(diǎn)并且重點(diǎn)介紹各種各樣的用法。廢話不多說,開車~
友情提示,由于本文涵蓋的內(nèi)容比較全面,不免篇幅稍長,中途請(qǐng)注意休息。
但是其實(shí),函數(shù)的本質(zhì)就是對(duì)象。確切一點(diǎn)來說,其實(shí)是第一類對(duì)象(first-class object)。關(guān)于第一類對(duì)象,wiki解釋如下:
第一類對(duì)象又稱第一類公民,在編程語言中指的是一個(gè)具有以下特性的實(shí)體:
能夠作為參數(shù)被傳遞
能夠從一個(gè)函數(shù)結(jié)果中返回
能夠被修改和賦值給變量
雖然看起來高大上,但是我們只要先記住,在js里函數(shù)也是對(duì)象,可以擁有自己的屬性和方法,而它和一般js對(duì)象的區(qū)別是:可以被調(diào)用,也就是可執(zhí)行。
當(dāng)然,函數(shù)還有一個(gè)明顯的特點(diǎn)就是,提供作用域:在函數(shù)作用域內(nèi)的變量都是局部變量,對(duì)外部不可見。由于js中其他代碼塊,比如for和while循環(huán)等并不提供作用域,所以有很多地方會(huì)利用函數(shù)來控制作用域。在后面會(huì)一一提到。
預(yù)備知識(shí)這一塊在之前講閉包的時(shí)候其實(shí)提到了一些,但是還是簡(jiǎn)單介紹下。
函數(shù)作用域在類似C語言的編程語言中,花括號(hào){}表示一個(gè)作用域:在作用域內(nèi)的變量對(duì)外不可見,這個(gè)稱為塊級(jí)作用域,但是在js中沒有塊級(jí)作用域,只有函數(shù)作用域:在函數(shù)體內(nèi)聲明的變量,在整個(gè)函數(shù)體內(nèi)有定義。
function fun(){ for(var j =1;j<10;j++){ } console.log(j)//10 } console.log(j)//undefined
這個(gè)例子中變量j定義在函數(shù)體中,那么在函數(shù)體內(nèi)可以訪問,在外部則無法訪問。
作用域鏈作用域鏈,就是一個(gè)類似鏈表的解構(gòu),它表示當(dāng)前代碼有權(quán)訪問的作用域的訪問順序。舉個(gè)例子:
var a = 1; function fun(){ var a = 2 console.log(a) } fun()//2
在這里,執(zhí)行fun()時(shí),作用域鏈上有2個(gè)作用域,第一個(gè)是fun,第二個(gè)是全局環(huán)境,按照順序,首先訪問內(nèi)容的作用域,找到了a變量,那么就不繼續(xù)尋找,如果這里沒有var a = 2,那么會(huì)繼續(xù)向外尋找,最終輸出的就是1。
只要記住,作用域鏈都是從當(dāng)前函數(shù)作用域向外一層層延伸的,所以內(nèi)部作用域可以訪問外部變量,反之則不行。
聲明提升看下這個(gè)例子:
function fun(){ console.log(a) var a = 1; } fun();//underfined
是不是覺得很奇怪,這里既沒有未定義報(bào)錯(cuò),也沒有輸出1,因?yàn)檫@里的代碼其實(shí)相當(dāng)于這樣寫:
function fun(){ var a; console.log(a) a = 1; } fun();//underfined
可以看到,其實(shí)變量a的聲明,相當(dāng)于被提前到當(dāng)前函數(shù)作用域的頂部,這就是所謂的聲明提升,但是要注意,聲明雖然提升了,賦值a=1并沒有被提升,否則這個(gè)例子應(yīng)該直接輸出1。
接下來再舉1個(gè)例子回顧下這一階段的知識(shí):
var a = 1; var b = 4; function fun (){ console.log(a); var a = 2; var b = 3; console.log(b); } fun (); console.log(b);
具體結(jié)果大家可以跑跑看。
函數(shù)的創(chuàng)建通常來說,有2種創(chuàng)建函數(shù)的方式:函數(shù)表達(dá)式、函數(shù)聲明。
函數(shù)表達(dá)式函數(shù)表達(dá)式通常具有如下形式:
var funA = function funName(param1,param2){ //函數(shù)體 }
當(dāng)然,更常見來說這里的funName是不寫的,寫與不寫的區(qū)別是,在不同瀏覽器中,獲得的函數(shù)對(duì)象中name屬性的值會(huì)被處理成不行的形式。
//這個(gè)例子可以在ie firefox webkit內(nèi)核的瀏覽器分別跑一下看看結(jié)果 var fun1 = function(){} var fun2 = function funName(){} console.log(fun1) console.log(fun2)
寫函數(shù)名字有個(gè)比較好用的地方是在遞歸的時(shí)候,可以很方便使用:
//階乘函數(shù) var fun1 = function recu(x){ if(x<=1) return 1; else return x*recu(x-1) }函數(shù)聲明
函數(shù)聲明形式一般如下:
function funName(){ //函數(shù)體 }
這個(gè)和函數(shù)表達(dá)式的區(qū)別就是,使用函數(shù)聲明的方式在js里會(huì)有"提升",而使用表達(dá)式方式寫沒有提升所以函數(shù)表達(dá)式定義的函數(shù)無法提前使用
fun1();//fun1 fun2();//報(bào)錯(cuò) function fun1 (){ console.log("fun1") } var fun2 = function(){ console.log("fun2") }
因?yàn)榍懊嬲f過,賦值部分不會(huì)提升,而函數(shù)表達(dá)式的寫法本質(zhì)上也是一個(gè)變量聲明和賦值,形如var x = function...,x的聲明被提升,但是右邊的賦值部分要等待代碼執(zhí)行到這句的時(shí)候才生效。
舉個(gè)更容易理解的例子:
console.log(fun2)//underfined fun2();//報(bào)錯(cuò) var fun2 = function(){ console.log("fun2") }
同理,變量fun2已聲明,但未賦值。所以這里console.log的時(shí)候不報(bào)錯(cuò),運(yùn)行的時(shí)候才報(bào)錯(cuò)??床欢?qǐng)?jiān)倩仡櫹骂A(yù)備知識(shí)的聲明提升部分。
函數(shù)參數(shù)函數(shù)的參數(shù)一般分成形參和實(shí)參,形參是函數(shù)定義時(shí)預(yù)期傳入的參數(shù),實(shí)參是函數(shù)調(diào)用時(shí)實(shí)際傳入?yún)?shù)。
參數(shù)數(shù)量不對(duì)等情況和argumentsJavascript沒有在函數(shù)調(diào)用時(shí)對(duì)實(shí)參做任何檢查。 所以可能出現(xiàn)以下情況:
當(dāng)傳入的實(shí)參比形參個(gè)數(shù)要少的時(shí)候,剩下的形參會(huì)被自動(dòng)設(shè)置為underfined,所以在寫函數(shù)的時(shí)候,我們經(jīng)常要注意是否要給參數(shù)一些默認(rèn)值
function fun(a){ var a = a || "" //如果傳入a就使用a,否則a設(shè)置為空字符串 }
如果我們的函數(shù)使用了可選參數(shù),那么可選參數(shù)的位置必須放在最后,否則,使用者調(diào)用時(shí)候,就要顯式傳入underfind,比如fun(underfined,a)表示第一個(gè)參數(shù)不傳入。
當(dāng)傳入的實(shí)參比形參個(gè)數(shù)要多的時(shí)候,我們可以通過標(biāo)識(shí)符arguments對(duì)象來獲得參數(shù)
function fun(a){ if(arguments.length>1)console.log(arguments[1])}; var a=1,b=2; fun(a,b);//2
這個(gè)例子中,通過arguments輸出了實(shí)參b的值。值得一提的是,arguments并不是數(shù)組,而是一個(gè)對(duì)象,只是恰好使用數(shù)字為索引
callee 和 calleres5的非嚴(yán)格模式下,我們可以使用callee 和 caller這兩個(gè)屬性,
callee 表示當(dāng)前正在執(zhí)行的函數(shù),通常用法是在匿名函數(shù)中寫遞歸調(diào)用
caller 表示調(diào)用當(dāng)前正在執(zhí)行函數(shù)的函數(shù),可以用來訪問調(diào)用棧,這個(gè)屬性是非標(biāo)準(zhǔn)的,但是大部分的瀏覽器都實(shí)現(xiàn)。更詳細(xì)的用法可以查看MDN。
函數(shù)的模式模式其實(shí)就是函數(shù)的各種應(yīng)用方式,也是本文的重點(diǎn)
api模式api模式主要是給函數(shù)提供更好的接口。
回調(diào)模式最前面已經(jīng)提到,函數(shù)是對(duì)象,并且可以被作為參數(shù)傳遞給其他的函數(shù)。
當(dāng)我們把函數(shù)A傳遞給函數(shù)B,并且讓B能夠在某一時(shí)刻執(zhí)行A,這種情況我們稱函數(shù)A是回調(diào)函數(shù)(callback function),簡(jiǎn)稱回調(diào)。
舉個(gè)例子,假設(shè)這樣一個(gè)背景:假設(shè)現(xiàn)在我們需要處理一批dom節(jié)點(diǎn),處理大概分2步,第一步,篩選出符合要求的一部分節(jié)點(diǎn),第二步,對(duì)這部分?jǐn)?shù)據(jù)做一些css樣式修改。那我們一般會(huì)先想到這樣寫:
//篩選函數(shù) function filterNodes(nodes){ var i = 0; var result = []; for(i = 0; i按照上面定義的2個(gè)函數(shù),先用filterNodes篩選符合要求額節(jié)點(diǎn),然后將結(jié)果作為operate函數(shù)的參數(shù),這樣邏輯上是完全沒問題的,只是有一個(gè)地方:其實(shí)我們已經(jīng)2次遍歷了符合要求的節(jié)點(diǎn):第一次是在篩選時(shí),第二次是在樣式操作時(shí)。這里有辦法優(yōu)化嗎?,如果我們直接把樣式操作直接寫到result.push()后面,是可以減少一次遍歷的,但是這樣filterNodes函數(shù)就不是一個(gè)純粹的篩選節(jié)點(diǎn)的數(shù)了。所以我們可以使用回調(diào)模式來解決,只需稍微修改下:
//篩選函數(shù) function filterNodes(nodes,callback){ var i = 0; var result = []; for(i = 0; i這樣改造之后,2個(gè)函數(shù)依然各自擁有自己的邏輯,而且我們可以通過調(diào)用filterNodes時(shí),傳遞不同參數(shù)的辦法,來控制我們想要的功能。
回調(diào)函數(shù)還有很多的常見用途:
異步事件監(jiān)聽
最常見的例子莫過于我們?yōu)槲臋n添加監(jiān)聽事件:document.addEventListener("click",[回調(diào)函數(shù)],false)有了回調(diào)模式以后,程序可以以異步的模式運(yùn)行:只有用戶觸發(fā)了某些交互行為,才會(huì)調(diào)用到我們指定的函數(shù)。
超時(shí)方法 setTimeout()和 setTimeInterval()
這兩個(gè)函數(shù)也一樣接受回調(diào)函數(shù)setTimeout([回調(diào)函數(shù)],200)軟件庫設(shè)計(jì)
返回函數(shù)
設(shè)計(jì)一個(gè)庫的時(shí)候,很重要的就是設(shè)計(jì)通用性和復(fù)用性的代碼,因?yàn)闊o法提前預(yù)測(cè)到需要的每一個(gè)功能,而且用戶也不會(huì)總是需要用到所有的功能,利用回調(diào)模式,很容易設(shè)計(jì)出具有核心功能有同時(shí)提供自選項(xiàng)的函數(shù)(比如前面提到的節(jié)點(diǎn)篩選函數(shù),核心功能是篩選,又能根據(jù)需要插入后續(xù)操作)。剛剛在回調(diào)函數(shù)部分,說的是函數(shù)作為另一個(gè)函數(shù)的參數(shù)傳遞,接下來說說函數(shù)作為另一邊函數(shù)的結(jié)果返回。看下面一個(gè)計(jì)時(shí)器例子:
var counter = function(){ var count = 0; return function(){ return count++ } } var f = counter(); f();//1 f();//2其實(shí)這里就是一個(gè)閉包的實(shí)例,關(guān)于閉包,在我的另一篇文章里有更詳細(xì)的描述點(diǎn)擊前往
配置對(duì)象配置對(duì)象模式其實(shí)就是讓用對(duì)象作為函數(shù)的參數(shù)。
這種模式經(jīng)常用在建立一個(gè)庫,或者寫的函數(shù)要提供給外部調(diào)用時(shí)。因?yàn)樗芴峁┖芎?jiǎn)潔的接口。假設(shè)這樣一個(gè)例子:function operate(para1,para2){}如果我們正在寫一個(gè)庫函數(shù),一開始我們預(yù)料到的參數(shù)只會(huì)有para1,para2,但是隨著不斷拓展,后來參數(shù)變多了,而且出現(xiàn)了一些可選參數(shù)para3,para4:
function operate(para1,para2,para3,para4...)此時(shí)我們需要很小心的把可選參數(shù)放在后面,使用者在調(diào)用的時(shí)候還必須很小心的對(duì)上位置,比如說:
operate(p1,p2,null,p4)//這里的null不可省略此時(shí),參數(shù)數(shù)量太多,使用起來需要很小心記住參數(shù)順序,很不方便。所以就要采用配置對(duì)象的寫法,即把參數(shù)寫成一個(gè)對(duì)象:
function operate(config){} var conf = { para1:..., para2:..., para4:..., } operate(con)這樣的寫法
優(yōu)點(diǎn)是:使用者不需要記住參數(shù)順序,代碼也顯得更簡(jiǎn)潔,
缺點(diǎn)是:使用時(shí)要嚴(yán)格記住參數(shù)的名稱,并且屬性名稱無法被壓縮
通常在操作dom對(duì)象的css樣式時(shí)候會(huì)用這樣的寫法,因?yàn)?b>css樣式有很多,但是名稱很容易記住,比如
var style ={ color:"..." border:"..." }柯里化start18/08/08編輯
柯里化內(nèi)容已添加,傳送門
end18/08/08編輯
柯里化的內(nèi)容比較長,難度也稍大,后續(xù)另開一篇來寫吧~~。
初始化模式初始化模式的主要作用是不污染全局命名空間,使用臨時(shí)變量來完成初始化任務(wù),使任務(wù)更加簡(jiǎn)潔
即時(shí)函數(shù)即時(shí)函數(shù)模式(immeddiate Function pattern),是一種支持在定義函數(shù)后立即執(zhí)行該函數(shù)的語法。也叫作自調(diào)用和自執(zhí)行函數(shù)(function(){ //函數(shù)內(nèi)容 }()) //也可以這樣寫 (function(){ //函數(shù)內(nèi)容 })()這里給出了即時(shí)函數(shù)的兩種寫法,它的作用是可以給初始化的代碼提供一個(gè)存放的空間:比如在頁面初始化時(shí),需要一些臨時(shí)變量來完成一次初始化,但是這些工作只需要執(zhí)行一次,執(zhí)行之后就不再需要這些臨時(shí)變量,那么我們就不必浪費(fèi)全局變量來創(chuàng)建這些變量,此時(shí)使用即時(shí)函數(shù),可以把所有代碼打包起來,并且不會(huì)泄露到全局作用域。比如:
(function(){ var initName = "" alert(initName) }());當(dāng)然,即時(shí)函數(shù)也可以傳遞參數(shù),
(function(initName){ alert(initName) }("hello"));同樣也可以有返回值:
var result = (function(){ return 1 }()); console.log(result)//1即時(shí)函數(shù)經(jīng)常用在寫一些自包含模塊,這樣的好處是可以確保頁面在有無該模塊的情況下都能良好運(yùn)行,很方便的可以分離出來,用于測(cè)試或者實(shí)現(xiàn),或者根據(jù)需要實(shí)現(xiàn)“禁用”功能。例如:
//moudle1.js (function(){ //模塊代碼 }//)按照這一的形式寫模塊??梢愿鶕?jù)需要加載模塊。
即時(shí)對(duì)象初始化這個(gè)模式和即使函數(shù)模式很相似,區(qū)別在于我們的函數(shù)寫在一個(gè)對(duì)象的方法上。通常我們?cè)谝粋€(gè)對(duì)象上寫上init方法,并且在創(chuàng)建對(duì)象之后立即執(zhí)行該方法。如下:
({ //初始化的屬性和配置 name:"Mike", age:"12", //其他方法 ... //初始化 init:function(){ ... } }).init();這個(gè)語法其實(shí)相當(dāng)于在創(chuàng)建一個(gè)普通的對(duì)象并且,然后在創(chuàng)建之后立刻調(diào)用init方法。這種做法和即時(shí)函數(shù)的目的是一致的:在執(zhí)行一次性初始化任務(wù)時(shí)保護(hù)全局命名空間。但是可以寫出更加復(fù)雜的結(jié)構(gòu),比如私有方法等,而在即時(shí)函數(shù)里面只能把所有的方法都寫成函數(shù)。
初始化時(shí)分支初始化時(shí)分支經(jīng)常用在某個(gè)生命周期中做一次性測(cè)試的情境中。所謂的一次性測(cè)試就是:在本次生命周期中,某些屬性不可能改變,比如瀏覽器內(nèi)核等。典型的例子是瀏覽器嗅探.
看過javacscript高級(jí)程序設(shè)計(jì)的話,對(duì)這個(gè)例子一定很眼熟:
var utils = { addListener:function(el,type,fn){ if(typeof window.addEvenrtListener === "function"){ el.addEventerListener(type,fn,false); } else if(typeof window.attachEvent === "function"){ //ie el.attachEvent("on" + type,fn) } else{ //其他瀏覽器 el.["on"+ type] = fn } } ...//刪除方法類似 }這個(gè)例子是為了寫一個(gè)能夠支持跨瀏覽器處理事件的方法,但是有個(gè)缺點(diǎn):每次在處理事件時(shí)都要檢測(cè)一次瀏覽器的類型。我們知道,其實(shí)在一次頁面的生命周期里,其實(shí)只需要檢測(cè)一次就夠了,所以可以利用初始化分支來這樣改寫:
var utils = { addListener:null } if(typeof window.addEvenrtListener === "function"){ utils.addListener = function(el,type,fn){ el.addEventerListener(type,fn,false); } } else if(typeof window.attachEvent === "function"){ //ie utils.addListener = function(el,type,fn){ el.attachEvent("on" + type,fn) } } else{ //其他瀏覽器 utils.addListener = function(el,type,fn){ el.["on"+ type] = fn } }這樣的話就可以在加載時(shí)完成一次嗅探。
性能模式性能模式,主要是在某些情況下加快代碼的運(yùn)行。
備忘模式備忘模式的核心是使用函數(shù)屬性,緩存能計(jì)算結(jié)果。以便后續(xù)調(diào)用時(shí)可以不必重新計(jì)算。
這么做的基礎(chǔ)主要是之前提到過的,函數(shù)本質(zhì)還是對(duì)象(這句話已經(jīng)重復(fù)n次了),既然是對(duì)象自然可以擁有屬性和方法,例子:var fun = function(key){ if(!fun.cache[key]){ //不存在對(duì)應(yīng)緩存,那么計(jì)算 var result = {} ...//計(jì)算過程 fun.cache[key] = result } return fun.cache[key] }這里舉了一個(gè)比較簡(jiǎn)單的例子,在獲取對(duì)應(yīng)數(shù)據(jù)的時(shí)候,先判斷有無緩存,有的話直接獲??;沒有的話計(jì)算一次并緩存到對(duì)應(yīng)位置。之后便無需重復(fù)計(jì)算。
當(dāng)然,這里的key我們假設(shè)是基本類型的值,如果是復(fù)雜類型的值,需要先序列化。
自定義模式
另外,在函數(shù)內(nèi)的fun可以通過前面提到的arguments.callee來代替,只要不在es5的嚴(yán)格模式下就行。自定義函數(shù)的原理很簡(jiǎn)單:首先創(chuàng)建一個(gè)函數(shù)并保存到一個(gè)變量f。然后在創(chuàng)建一個(gè)新函數(shù),也保存在這個(gè)變量f,那么f最終指向的應(yīng)該是新的函數(shù)。那么如果我們讓這個(gè)過程發(fā)生在舊的函數(shù)內(nèi)部,那么就實(shí)現(xiàn)了惰性函數(shù)。話不多說,看例子:
var fun = function(){ console.log("在這里執(zhí)行一些初始化工作") fun = function(){ console.log("在這里執(zhí)行正常工作時(shí)需要執(zhí)行的工作") } } fun();//在這里執(zhí)行一些初始化工作 fun();//在這里執(zhí)行正常工作時(shí)需要執(zhí)行的工作 fun();//在這里執(zhí)行正常工作時(shí)需要執(zhí)行的工作在這里我們執(zhí)行了一次初始化任務(wù)以后,函數(shù)就變成了正常的函數(shù),之后的執(zhí)行就可以減少工作。
總結(jié)這是2018年寫的第一篇長文(其實(shí)一共就寫了2篇,哈哈哈)希望今年自己可以好好努力,把“深入”系列貫徹到底。也希望大家都有所進(jìn)步。
然后依然是每次都一樣的結(jié)尾,如果內(nèi)容有錯(cuò)誤的地方歡迎指出;如果對(duì)你有幫助,歡迎點(diǎn)贊和收藏,轉(zhuǎn)載請(qǐng)征得同意后著明出處,如果有問題也歡迎私信交流,主頁添加了郵箱地址~溜了
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92411.html
摘要:模板解析器原理本文來自深入淺出模板編譯原理篇的第九章,主要講述了如何將模板解析成,這一章的內(nèi)容是全書最復(fù)雜且燒腦的章節(jié)。循環(huán)模板的偽代碼如下截取模板字符串并觸發(fā)鉤子函數(shù)為了方便理解,我們手動(dòng)模擬解析器的解析過程。 Vue.js 模板解析器原理 本文來自《深入淺出Vue.js》模板編譯原理篇的第九章,主要講述了如何將模板解析成AST,這一章的內(nèi)容是全書最復(fù)雜且燒腦的章節(jié)。本文未經(jīng)排版,真...
摘要:預(yù)解析聲明告知瀏覽器在全局作用域中有一個(gè)變量名為的變量。執(zhí)行代碼的就是棧內(nèi)存,作用域也是棧內(nèi)存。關(guān)鍵字在中主要研究都是函數(shù)中的中的代表的是當(dāng)前行為執(zhí)行的主體方法,函數(shù),事件中的上下文代表的是當(dāng)前行為執(zhí)行的環(huán)境區(qū)域例如小明在沙縣小吃吃蛋炒飯。 基本認(rèn)識(shí) 數(shù)據(jù)類型 基本數(shù)據(jù)類型 string, number, null, boolean, undefined 引用數(shù)據(jù)類型 object: ...
摘要:在高級(jí)的技巧中會(huì)用來創(chuàng)建作用域安全的構(gòu)造函數(shù)。運(yùn)算符希望左操作數(shù)是一個(gè)對(duì)象,右操作數(shù)表示對(duì)象的類。中對(duì)象的類似通過初始化它們的構(gòu)造函數(shù)來定義的。為了理解運(yùn)算符是如何工作的,必須首先理解原型鏈原型鏈可作為的繼承機(jī)制。 在js高級(jí)的技巧中會(huì)用instanceof來創(chuàng)建作用域安全的構(gòu)造函數(shù)。instanceof運(yùn)算符希望左操作數(shù)是一個(gè)對(duì)象,右操作數(shù)表示對(duì)象的類。如果左側(cè)的對(duì)象是右側(cè)類的...
摘要:本計(jì)劃一共期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃,點(diǎn)擊查看前端進(jìn)階的破冰之旅本期推薦文章深入之執(zhí)行上下文棧和深入之變量對(duì)象,由于微信不能訪問外鏈,點(diǎn)擊閱讀原文就可以啦。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第二天。 本計(jì)劃一共28期,每期...
摘要:下面是用實(shí)現(xiàn)轉(zhuǎn)成抽象語法樹如下還支持繼承以下是轉(zhuǎn)換結(jié)果最終的結(jié)果還是代碼,其中包含庫中的一些函數(shù)。可以使用新的易于使用的類定義,但是它仍然會(huì)創(chuàng)建構(gòu)造函數(shù)和分配原型。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 15 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過了前面的章節(jié),可以在這里找到它們: JavaScript 是...
閱讀 3309·2021-09-08 09:45
閱讀 1260·2019-08-30 15:53
閱讀 1532·2019-08-30 14:12
閱讀 987·2019-08-29 17:01
閱讀 2578·2019-08-29 15:35
閱讀 401·2019-08-29 13:09
閱讀 1978·2019-08-29 12:32
閱讀 3089·2019-08-26 18:37