Vue源码:抽象语法树

// 缓存对象

var cache = {};

// 创建一个函数,功能是返回下标为n的这项的数字

function fib(n) {

// 判

真题解析、进阶学习笔记、最新讲解视频、实战项目源码、学习路线大纲
详情关注公中号【编程进阶路】

断缓存对象中有没有这个值,如果有,直接用

if (cache.hasOwnProperty(n)) {

return cache[n];

}

// 缓存对象没有这个值

// 看下标n是不是0或者是不是1,如果是,就返回常数1

// 如果不是,就递归

var v = n == 0 || n == 1 ? 1 : fib(n - 1) + fib(n - 2);

// 写入缓存。也就是说,每算一个值,就要把这个值存入缓存对象。

cache[n] = v;

return v;

}

for (let i = 0; i <= 9; i++) {

console.log(fib(i));

}

Title

相关算法储备 — 栈

=====================================================================

  • 栈(stack )又名堆栈,它是一种运算受限的线性表,仅在表尾能进行入和删除操作。这一端被称为栈顶,相对地,把另一端称为栈底。

  • 向一个栈插入新元素又称作进栈、入栈或压栈;从一个栈删除元素又称作出栈或退栈。

  • 后进先出(LIFO )特点:栈中的元素,最先进栈的必定是最后出栈,后进栈的一定会先出栈

  • JavaScript 中,栈可以用数组模拟。需要限制只能使用push() 和pop() ,不能使用unshift() 和shift()。即,数组尾是栈顶。

  • 当然,可以用面向对象等手段,将栈封装的更好。

在这里插入图片描述

利用"栈"的题目

试编写"智能重复"smartRepeat函数,实现:

  • 将3[abc]变为abcabcabc

  • 将3[2[a]2[b]]变为aabbaabbaabb

  • 将2[1[a]3[b]2[3[c]4[d]]]变为abbbcccddddcccddddabbbcccddddcccdddd

不用考虑输入字符串是非法的情况,比如:

  • 2[a3[b]]是错误的,应该补一个1,即2[1[a]3[b]]

  • [abc]是错误的,应该补一个1,即1[abc]

使用"栈"优雅接替

====================================================================

  • 词法分析的时候,经常要用到栈这个数据结构;

  • 初学者大坑:栈的题目和递归非常像,这类题目给人的感觉都是用递归解题。信心满满动手开始写了,却发现递归怎么都递归不出来。此时就要想到,不是用递归,而是用栈。

在这里插入图片描述

在这里插入图片描述

Document

正则表达式的相关方法

=====================================================================

在这里插入图片描述

在这里插入图片描述

手写实现AST抽象语法树

=======================================================================

在这里插入图片描述

在这里插入图片描述

识别attrs

==================================================================

在这里插入图片描述

完整代码

===============================================================

index.js


import parse from ‘./parse.js’;

var templateString = `

你好

    • A
    • B
    • C
    • `;

      const ast = parse(templateString);

      console.log(ast);

      parse.js


      import parseAttrsString from ‘./parseAttrsString.js’;

      // parse函数,主函数

      export default function (templateString) {

      // 指针

      var index = 0;

      // 剩余部分

      var rest = ‘’;

      // 开始标记

      var startRegExp = /<([a-z]+[1-6]?)(\s[<]+)?>/;

      // 结束标记

      var endRegExp = /^</([a-z]+[1-6]?)>/;

      // 抓取结束标记前的文字

      var wordRegExp = /([<]+)</[a-z]+[1-6]?>/;

      // 准备两个栈

      var stack1 = [];

      var stack2 = [{ ‘children’: [] }];

      while (index < templateString.length - 1) {

      rest = templateString.substring(index);

      // console.log(templateString[index]);

      if (startRegExp.test(rest)) {

      // 识别遍历到的这个字符,是不是一个开始标签

      let tag = rest.match(startRegExp)[1];

      let attrsString = rest.match(startRegExp)[2];

      // console.log(‘检测到开始标记’, tag);

      // 将开始标记推入栈1中

      stack1.push(tag);

      // 将空数组推入栈2中

      stack2.push({ ‘tag’: tag, ‘children’: [], ‘attrs’: parseAttrsString(attrsString) });

      // 得到attrs字符串的长度

      const attrsStringLength = attrsString != null ? attrsString.length : 0;

      // 指针移动标签的长度加2再加attrString的长度,为什么要加2呢?因为<>也占两位

      index += tag.length + 2 + attrsStringLength;

      } else if (endRegExp.test(rest)) {

      // 识别遍历到的这个字符,是不是一个结束标签

      let tag = rest.match(endRegExp)[1];

      // console.log(‘检测到结束标记’, tag);

      let pop_tag = stack1.pop();

      // 此时,tag一定是和栈1顶部的是相同的

      if (tag == pop_tag) {

      let pop_arr = stack2.pop();

      if (stack2.length > 0) {

      stack2[stack2.length - 1].children.push(pop_arr);

      }

      } else {

      throw new Error(pop_tag + ‘标签没有封闭!!’);

      }

      // 指针移动标签的长度加3,为什么要加2呢?因为</>也占3位

      index += tag.length + 3;

      } else if (wordRegExp.test(rest)) {

      // 识别遍历到的这个字符,是不是文字,并别不能是全空

      let word = rest.match(wordRegExp)[1];

      // 看word是不是全是空

      if (!/^\s+$/.test(word)) {

      // 不是全是空

      // console.log(‘检测到文字’, word);

      // 改变此时stack2栈顶元素中

      stack2[stack2.length - 1].children.push({ ‘text’: word, ‘type’: 3 });

      }

      总结

      三套“算法宝典”

      28天读完349页,这份阿里面试通关手册,助我闯进字节跳动

      算法刷题LeetCode中文版(为例)

      人与人存在很大的不同,我们都拥有各自的目标,在一线城市漂泊的我偶尔也会羡慕在老家踏踏实实开开心心养老的人,但是我深刻知道自己想要的是一年比一年有进步。

      最后,我想说的是,无论你现在什么年龄,位于什么城市,拥有什么背景或学历,跟你比较的人永远都是你自己,所以明年的你看看与今年的你是否有差距,不想做咸鱼的人,只能用尽全力去跳跃。祝愿,明年的你会更好!

      由于篇幅有限,下篇的面试技术攻克篇只能够展示出部分的面试题,详细完整版以及答案解析,有需要的可以关注

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值