跟著B站學VUE2源碼之第四課:AST抽象語法樹

課程內(nèi)容:

  • 3個常見算法思想:指針思想、遞歸緩存和棧
  • AST的形成算法
  • 手寫AST及優(yōu)化

AST抽象語法樹:

1、本質上是個JS對象,作用是為了讓模板語法變成正常的HTML語法
2、用js來表現(xiàn)HTML結構的東西實際上就是AST(抽象語法樹)

虛擬節(jié)點和AST有什么關系?

1、vue底層(vue-loader)是在用字符串的視角來識別html標簽
2、整個流程如下:
模板語法 => AST抽象語法樹 => 渲染函數(shù)(h函數(shù))=> 虛擬節(jié)點 => 經(jīng)過diff和patch => 渲染成界面

AST的實現(xiàn)函數(shù)parse函數(shù)

parse函數(shù)的主函數(shù),實現(xiàn)輸入一個模板結構 轉換成包含dom信息的層級對象結構


parse函數(shù)的作用

算法儲備

1、指針思想

JS中的指針就是下標位置,指正就是偏移量,第一個數(shù)的偏移量是0

算法題一: 試圖尋找字符串當中連續(xù)重復次數(shù)最多的字符
let str = 'aaaaaaabbbbbbbccccccccccccccccccddddddddddddd'
// 定義指針
let i = 0
let j = 1
// 尋找最多的次數(shù)與字符
let maxRepeat = 0
let maxRepeatStr = ''
// 進入循環(huán) 
while (i <= str.length - 1) {
    if (str[i] !== str[j]) {
        // 與當前重復次數(shù)最多的進行比較 和賦值
        if (j - i > maxRepeat) {
            maxRepeat = j - i
            maxRepeatStr = str[i]
        }
        // 讓指針i 追上指針J
        i = j
    }
    j++
}
console.log(maxRepeatStr + '重復了' +maxRepeat +'次');
2、遞歸深入-菲波那契數(shù)列
// 算法題二:遞歸深入,試著輸出菲波那契數(shù)列的前十項 [1、1、2、3、5、8、13、21]

// 1. 簡單實現(xiàn)
// 創(chuàng)建一個函數(shù),返回功能下標為N的這項的數(shù)字
function feb1(n) {
    console.count('觸發(fā)次數(shù)') // 觸發(fā)次數(shù): 99
    return n == 0 || n ==1 ? 1 : feb1(n-1) + feb1(n-2)
}

// 2. 利用緩存
// cache思想,利用緩存對象,解決大量重復計算的問題
let cache = {}
function feb2(n) {
    console.count('觸發(fā)次數(shù)') // 觸發(fā)次數(shù): 19
    if (n in cache) {
        return cache[n]
    }
    let val = n == 0 || n ==1 ? 1 : feb2(n-1) + feb2(n-2)
    cache[n] = val
    return val
}

// 測試
let n = 0
while (n <= 6) {
    console.log(feb2(n));
    n++
}
3、遞歸深入-高維數(shù)組

小技巧:只要出現(xiàn)了規(guī)則復現(xiàn),就可以使用遞歸。tips:規(guī)則復現(xiàn)

// 算法題三:將高維數(shù)組 變成一個key:value 和 children:arr的數(shù)組對象

// 1. 循環(huán)實現(xiàn)
let myArr = [1, 2, 3, [4, 5, [6, 7, 8, [9, 10]]]]
function fn(arr) {
    let resultArr = []
    for (let i = 0; i < arr.length; i++) {
        if (typeof arr[i] == 'number') {
            resultArr.push({
                'value': arr[i]
            })
        } else if (Array.isArray(arr[i])) {
            resultArr.push({
                'children': fn(arr[i])
            })
        }
    }
    return resultArr
}
// console.log(fn(myArr));

// 2. 使用映射map實現(xiàn) item可能是數(shù)組也可能是數(shù)字
// 注意:寫法一的遞歸次數(shù)要大大小于寫法二
let myArr2 = [1, 2, 3, [4, 5, [6, 7, 8, [9, 10]]]]
function convert(item) {
    if (typeof item == 'number') {
        return {
            'value': item
        }
    } else if (Array.isArray(item)) {
        return {
            children: item.map(_item => convert(_item))
        }
    }
}
console.log(convert(myArr2));
4、棧
  • 詞法分析的時候 需要經(jīng)常要用到棧這個結構,是非常著名的數(shù)據(jù)結構,可以輔助來解決算法題目
  • JS中的棧,可以用數(shù)組模擬,只能使用push 和 pop 方法操作進棧和出棧。注意:棧是后進先出!
// 題目:smartRepeat函數(shù)
// 試編寫“智能重復” 實現(xiàn):將3[abc]變?yōu)閍bcabcabc、將3[2[a]2[b]]變?yōu)閍abbaabbaabb
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容