首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

手写 JS 引擎来解释一道赋值面试题

简易 JS 引擎实现思路分析 Parser 可以是任意的 JS Parser,我们直接用 @babel/parser。...自然可以想到,解释 ObjectExpression 节点就是取出 AST 中的数据构造一个对象返回: 再比如 let a = { n: 1} 这条赋值语句,它对应的是 VariableDeclaration...节点,下面有多个 VariableDeclarator 子节点,这是因为一条声明语句可以声明多个变量,比如 let a = 1, b =1; 而具体的声明 VariableDeclarator 里分别有...声明语句的解释就是在作用域(我们声明的 Map)中设置下就行: VariableDeclaration(node) { node.declarations.forEach((item) => {...具体的声明 VariableDeclarator 就是在 scope 中设置变量名和它的值。 变量名是 node.id 的执行结果,如果声明过就报错,因为只能声明一次。

88821

123. 精读《用 Babel 创造自定义 JS 语法》

个人学习也是如此,养成定期学习的习惯,比在培训班突击几个月更有用,学会在生活中规律的学习,甚至好过读几年名牌大学。...所以我们的目的并不是像文章标题说的 - 创造一个自定义 JS 语法,因为你创造的语法只会让 JS 复杂体系更加混乱,但可以让你理解 Babel 解析标准 JS 语法的原理,以及看待新语法提案时,拥有从实现层面思考的能力...由于 @@ 是我们创造的语法,所以我们第一个任务就是让 babel 词法分析可以识别它。...语法 词法已经可以将 @@ 解析为 atat Token,下一步我们就要利用这个 Token,让生成的 AST 结构中包含柯里化函数的信息,并利用 babel 插件在解析时实现柯里化功能。...同理,增加一个 curry 属性就可以实现第一步了: 要实现如上效果,只需在词法分析 parser/statement 文件的 parseFunction 处新增 atat 解析即可: // packages

51010
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Babel 的工作原理以及怎么写一个 Babel 插件

    做与不做 注意很重要的一点就是,Babel 只是转译新标准引入的语法,比如: 箭头函数 let / const 解构 哪些在 Babel 范围外?...整个解析过程分为两个步骤: 分词:将整个代码字符串分割成语法单元数组 语法分析:建立分析语法单元之间的关系 分词 语法单元通俗点说就是代码中的最小单元,不能再被分割,就像原子是化学变化中的最小粒子一样...语义分析则是将得到的词汇进行一个立体的组合,确定词语之间的关系。...考虑到编程语言的各种从属关系的复杂性,语义分析的过程又是在遍历得到的语法单元组,相对而言就会变得更复杂。...简单来说语法分析是对语句和表达式识别,这是个递归过程,在解析中,Babel 会在解析每个语句和表达式的过程中设置一个暂存器,用来暂存当前读取到的语法单元,如果解析失败,就会返回之前的暂存点,再按照另一种方式进行解析

    2.4K30

    什么是AST

    有了这棵树,我们就可以通过操纵这颗树,精准的定位到声明语句、赋值语句、运算语句等等,实现对代码的分析、优化、变更等操作。...用一个叫做jsparser的工具来转化, 整个解析过程主要分为以下两个步骤: 分词:将整个代码字符串分割成最小语法单元数组 语法分析:在分词基础上建立分析语法单元之间的关系 什么是语法单元呢?...然后就是语法分析,上面我们已经得到了我们分词的结果,需要将词汇进行一个立体的组合,确定词语之间的关系,确定词语最终的表达含义。简单来说语法分析是对语句和表达式识别,确定之前的关系,这是个递归过程。...上面我们通过语法分析,可以得到如下结果: { "type": "Program", "body": [ { "type": "VariableDeclaration...js,这里就可以进行一些操作了,我们可以修改抽象语法树,然后再将其转化为js语言,这样就达到了将某一个版本的js转化为另外一个版本的js的作用。

    1.5K51

    如何优雅地 hack 用户的代码

    前言:做基础技术的时候,会经常碰到一个问题就是如何让自己提供的代码对用户少侵入,无感。...比如我提供了一个 SDK 收集 Node.js 进程的 HTTP 请求耗时,最简单的方式就是给用户提供一个 request 方法,然后让用户统一调用,这样我就可以在 request 里拿到这些数据。...在 Node.js 中,统计 JS 函数的耗时通常的做法是 cpu profile,但是这种方式只能拿到一段时间的耗时,如果我想实时收集耗时数据,cpu profile 就有点难搞,最直接的就是定时收集...entryNode = b.variableDeclaration('const', [b.variableDeclarator(b.identifier('start'), b.callExpression...不过这种方式的难点在重写代码的逻辑,风险也比较大,但是如果我们解决了这个问题后,我们就可以随便 hack 用户的代码,做我们想做的事情,当然,是正事。

    64920

    手把手带你走进Babel的编译世界

    AST 结构 随着 JavaScript 的发展,为了统一ECMAScript标准的语法表达。社区中衍生出了ESTree Spec,是目前社区所遵循的一种语法表达标准。...函数体中: 声明了一个const类型变量a,值为 1 执行了一个 console.log 语句 将上述代码粘贴至AST Explorer,结果如图所示: 3.png 接下来我们继续分析内部结构,以const...a = 1为例: 4.png 变量声明在 AST 中对应的就是 type 为VariableDeclaration的节点。...而 type 为VariableDeclarator的节点代表的就是a=1这种声明语句,其中包含id和init属性。 id即为Identifier,其中的name值对应的就是变量名称。...Babel 概述 Babel 是一个 JavaScript 编译器,在实际开发过程中通常借助Babel来完成相关 AST 的操作。

    55520

    babel ES6 转换 ES5 实现原理

    前言 前面写过一篇简单的 AST 抽象语法树的文章简述 AST 抽象语法树。今天来看一下在 babel 中是如何将 ES6 转换为 ES5 的 。...在 webpack 中 babel-loader 就是通过这个包实现。babylon:babel 的词法解析器。将原始代码逐个字母地像扫描机一样读取分析得出 AST 语法树结构。...babel-polyfill:JS 标准新增的原生对象和 API 的 shim,实现上仅仅是 core-js 和 regenerator-runtime两个包的封装。...es2017 / env / stage-0 / stage-4 其中 es20xx 表示转换成该年份批准的标准,env 是最新标准,stage-0 和 stage-4 是实验版)转换成新的 AST...plugins 和 presets 通常在 .babelrc 文件中配置。 3. Generator 生成 第三步是将新的 AST 语法树对象再生成浏览器都可以识别的 ES5 语法。

    85820

    逆向进阶,利用 AST 技术还原 JavaScript 混淆代码

    [03] 语法分析 语法分析是编译过程的一个逻辑阶段,语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,比如“程序”,“语句”,“表达式”等,前面的例子中,isPanda('') 就会被分析为一条表达语句...,其值有数字也有字符串,我们在 AST 中可以看到对应的类型为 NumericLiteral 和 StringLiteral: [09] 然后我们声明了一个 visitor 对象,然后定义对应类型的处理方法...首先观察一下 AST 语法树,原语句只有一个 VariableDeclaration 节点,现在增加了一个: [10] 那么我们的思路就是在遍历节点时,遍历到 VariableDeclaration 节点...,就在其后面增加一个 VariableDeclaration 节点,生成 VariableDeclaration 节点,可以使用 types.variableDeclaration() 方法,在 types...是 VariableDeclarator 类型的节点组成的列表,所以我们可以先写出以下 visitor 部分的代码,其中 path.insertAfter() 是在该节点之后插入新节点的意思: const

    5.9K54

    前端AST详解,手写babel插件

    callee 属性是一个表达式节点,表示函数,arguments 是一个数组,元素是表达式节点,表示函数参数列表.图片MemberExpression(成员表达式节点):即表示引用对象成员的语句,object...图片VariableDeclarator(变量声明的描述):id 表示变量名称节点,init 表示初始值的表达式,可以为 null图片IfStatement(if表达式):if(true),test 属性表示...访问者模式,即将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式,简单来说,就是定义了用于在一个树状结构中获取具体节点的方法...从而可以避免在 npm 仓库中 babel 相关名称被抢注的问题,并且采用了Babel Monorepo风格的仓库。...@babel/types:用于检验、构建和改变AST树的节点@babel/cli 是 Babel 提供的命令行,它可以在终端中通过命令行方式运行,编译文件。

    58740

    JS代码之混淆

    即便你的程序也许在运行时报错,但都不会影响 AST 解析(除非语法错误),在 js 逆向中,通过静态分析还原出相对容易看的出的代码有对于代码分析,而对于一些需要知道某一变量执行后的结果静态分析是做不到的...>): VariableDeclaration 可以看到第一个参数就是关键字,而第二个则一个数组,其中节点为VariableDeclarator,关于variableDeclaration与 VariableDeclarator...由于我们这里只是声明一个变量 a,所有数组成员只给一个便可,如果要生成 b,c 这些变量,就传入对应的VariableDeclarator即可 这时候在查看下 VariableDeclarator 方法参数...在查看 numericLiteral 中的参数,就只给一个数值,那么便传入 100。...binding​ scope.getBinding() 接收一个参数,可用于获取标识符的绑定,这里的 binding 可能会有些抽象,在一开始的例子中初次接触到 traverse(ast, { VariableDeclarator

    22.1K10

    一处JS反调试引发的思考

    起因 白帽子们挖Web漏洞时,JavaScript信息是至关重要的一环 从JS中可以得到隐藏接口等信息,然后尝试挖掘越权,SQL注入和上传等洞 笔者刚入门时候曾用这种办法挖到了一些CNVD,算是收获颇丰...,不过我不太懂JS,第一次遇到感觉挺有趣的 起因是发现调试该JS时候会发现卡死,但目标网站在正常使用该JS脚本 分析 做全局JavaScript做了一定的分析后,最终跟踪到代码如下 注意到其中有类似正则的地方...*}因此返回false 继续看后面的表达式,如果为true会从NsTJKl数组中移除1否则移除0,暂不分析这里的用途 this['NsTJKl'] = [0x1, 0x0, 0x0]; 函数的return...,本质是一处的正则没有匹配到 问题来了,为什么目标网站的正则可以匹配到,但我本地无法匹配到 原因不难,目标网站的JS是压缩后的代码 this['HILIkx'] = function () {return...'newState';}; 逆向者在本地尝试做破解的时候,会将代码格式化(无论chrome还是vscode里都会很容易地进行格式化) 格式化后的代码不满足条件,所以会进入死循环 绕过方式其实也简单,还原回压缩格式即可

    38720

    「 giao-js 」用js写一个js解释器

    在英语中,当我们遇到这样一个语句时: Javascript is the best language in the world 我们会下意识地把句子分解成一个个单词: +---------------...": Subject "is the best language": Predicate "language": Object Javascript 在语法中是一个主语名词,其余的是一个没有什么意义的句子叫做谓语...我们可以看到这段代码中存在 4 种节点类型,下面我们简单的介绍一下它们: Program 根节点,即代表一整颗抽象语法树,body 属性是一个数组,包含了多个 Statement 节点。...从语法树中我们可以看到三个陌生的节点类型,来看看它们分别代表什么意思: VariableDeclaration 变量声明,kind 属性表示是什么类型的声明,因为 ES6 引入了 const/let。...},块里边可以包含多个其他的语句,所以有一个 body 属性,是一个数组,表示了块里边的多个语句。

    46.5K20

    【Babel】293- 初学 Babel 工作原理

    我们可以在 https://babel.docschina.org/repl 尝试一下。 一个小?...为 add 的ArrowFunctionExpression(箭头函数): params(函数入参):a 和 b 函数体:函数主体是一个BinaryExpression(二项式),一个标准的二项式分为三部分...词法分析 词法分析阶段可以看成是对代码进行“分词”,它接收一段源代码,然后执行一段 tokenize 函数,把代码分割成被称为Tokens 的东西。...语法分析 词法分析之后,代码就已经变成了一个 Tokens 数组了,现在需要通过语法分析把 Tokens 转化为上面提到过的 AST。 说来惭愧,这里没有想到很好的思路来实现一个 parse 函数。...所以,操作 AST 也就是操作其中的节点,可以增删改这些节点,从而转换成实际需要的 AST。 更多的节点规范可以在https://github.com/estree/estree中查看。

    44520

    一文助你搞懂 AST

    修改函数名字 此时我们发现函数的名字在 type 为 Identifier 的时候就是该函数的名字,我们就可以直接修改它便可实现一个更改函数名字的 AST 工具 ?...,说白了其实就是拼成另一颗树的结构,然后生成新的代码,就可以完成代码的转换 访问者模式 在 babel 中,我们开发 plugins 的时候要用到访问者模式,就是说在访问到某一个路径的时候进行匹配,然后在对这个节点进行修改...我们细看 AST 结构,函数表达式中的 BlockStatement 中的 body 是一个 ReturnStatement,所以我们还需要生成一个 ReturnStatement 现在我们就可以改写...) 那我们要做的就很简单了,就是把 数组表达式转换为调用表达式就可以 分析类型 这段代码的核心生成一个 callExpression 调用表达式,所以对应官网上的类型,我们分析需要用到的 api 先来分析...一般的,在源代码的翻译和编译过程中,语法分析器创建出分析树。一旦 AST 被创建出来,在后续的处理过程中,比如语义分析阶段,会添加一些信息。可参考抽象语法树和具体语法树有什么区别?

    2.5K60

    前端AST详解,手写babel插件

    callee 属性是一个表达式节点,表示函数,arguments 是一个数组,元素是表达式节点,表示函数参数列表MemberExpression(成员表达式节点):即表示引用对象成员的语句,object...VariableDeclarator(变量声明的描述):id 表示变量名称节点,init 表示初始值的表达式,可以为 null IfStatement(if表达式):if(true),test 属性表示...访问者模式,即将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式,简单来说,就是定义了用于在一个树状结构中获取具体节点的方法...从而可以避免在 npm 仓库中 babel 相关名称被抢注的问题,并且采用了Babel Monorepo风格的仓库。...@babel/types:用于检验、构建和改变AST树的节点@babel/cli 是 Babel 提供的命令行,它可以在终端中通过命令行方式运行,编译文件。

    31410
    领券