国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

面試官: 你了解過Babel嗎?寫過Babel插件嗎? 答: 沒有。卒

開發(fā) 前端
了解過抽象語法樹,又稱AST,有學(xué)習(xí)過,也寫過一個(gè)基于AST的乞丐版模板引擎,先是詞法解析token,然后生產(chǎn)抽象語法樹,然后更改抽象語法樹,當(dāng)然這是插件做的事情,最后根據(jù)新的AST生成代碼。

面試大廠,其中有那么一個(gè)問題:

1.你了解過Babel嗎?

了解過抽象語法樹,又稱AST,有學(xué)習(xí)過,也寫過一個(gè)基于AST的乞丐版模板引擎,先是詞法解析token,然后生產(chǎn)抽象語法樹,然后更改抽象語法樹,當(dāng)然這是插件做的事情,最后根據(jù)新的AST生成代碼。

2.寫過Babel插件嗎

沒有,只是看過相關(guān)文檔

3.如果讓你寫一個(gè)插件,你能寫的出來嗎?

啊,這,我試試!

遂卒....

開玩笑的,既然提到了,又沒回答上來什么,哎喲我這暴脾氣,一想到今晚就睡不著,連夜把它擼了。

那么我們來從零寫個(gè)插件吧。

寫一個(gè)預(yù)計(jì)算簡單表達(dá)式的插件

預(yù)覽

Before:

const result = 1 + 2 + 3 + 4 + 5;

After:

const result = 15;

以上的例子可能大家不會(huì)經(jīng)常遇到,因?yàn)樯祒才會(huì)這么寫,但是有可能你會(huì)這么寫

setTimeout(function(){
// do something
}, 1000 * 2) // 插件要做的事,就是把 1000 * 2 替換成 2000

開工

在寫代碼之前,你需要明白Babel它的原理,簡單點(diǎn)說:Babel解析成AST,然后插件更改AST,最后由Babel輸出代碼。

那么Babel的插件模塊需要你暴露一個(gè)function,function內(nèi)返回visitor。

module.export = function(babel){
return {
visitor:{
}
}
}

visitor是對(duì)各類型的AST節(jié)點(diǎn)做處理的地方,那么我們?cè)趺粗繠abel生成了的AST有哪些節(jié)點(diǎn)呢?

很簡單,你可以把Babel轉(zhuǎn)換的結(jié)果打印出來,或者這里有傳送門: AST explorer:https://astexplorer.net/

這里我們看到 const result = 1 + 2中的1 + 1是一個(gè)BinaryExpression節(jié)點(diǎn),那么在visitor中,我們就處理這個(gè)節(jié)點(diǎn)

var babel = require('babel-core');
var t = require('babel-types');
const visitor = {
BinaryExpression(path) {
const node = path.node;
let result;
// 判斷表達(dá)式兩邊,是否都是數(shù)字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {
// 根據(jù)不同的操作符作運(yùn)算
switch (node.operator) {
case "+":
result = node.left.value + node.right.value;
break
case "-":
result = node.left.value - node.right.value;
break;
case "*":
result = node.left.value * node.right.value;
break;
case "/":
result = node.left.value / node.right.value;
break;
case "**":
let i = node.right.value;
while (--i) {
result = result || node.left.value;
result = result * node.left.value;
}
break;
default:
}
}
// 如果上面的運(yùn)算有結(jié)果的話
if (result !== undefined) {
// 把表達(dá)式節(jié)點(diǎn)替換成number字面量
path.replaceWith(t.numericLiteral(result));
}
}
};
module.exports = function (babel) {
return {
visitor
};
}

插件寫好了,我們運(yùn)行下插件試試

const babel = require("babel-core");
const result = babel.transform("const result = 1 + 2;",{
plugins:[
require("./index")
]
});
console.log(result.code); // const result = 3;

與預(yù)期一致,那么轉(zhuǎn)換 const result = 1 + 2 + 3 + 4 + 5;呢?

結(jié)果是: const result = 3 + 3 + 4 + 5;

這就奇怪了,為什么只計(jì)算了1 + 2之后,就沒有繼續(xù)往下運(yùn)算了?

我們看一下這個(gè)表達(dá)式的AST樹

你會(huì)發(fā)現(xiàn)Babel解析成表達(dá)式里面再嵌套表達(dá)式。

表達(dá)式( 表達(dá)式( 表達(dá)式( 表達(dá)式(1 + 2) + 3) + 4) + 5)

而我們的判斷條件并不符合所有的,只符合1 + 2

// 判斷表達(dá)式兩邊,是否都是數(shù)字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {}

那么我們得改一改

第一次計(jì)算1 + 2之后,我們會(huì)得到這樣的表達(dá)式

表達(dá)式( 表達(dá)式( 表達(dá)式(3 + 3) + 4) + 5)

其中 3 + 3又符合了我們的條件, 我們通過向上遞歸的方式遍歷父級(jí)節(jié)點(diǎn) 又轉(zhuǎn)換成這樣:

表達(dá)式( 表達(dá)式(6 + 4) + 5)
表達(dá)式(10 + 5)
15
// 如果上面的運(yùn)算有結(jié)果的話
if (result !== undefined) {
// 把表達(dá)式節(jié)點(diǎn)替換成number字面量
path.replaceWith(t.numericLiteral(result));
let parentPath = path.parentPath;
// 向上遍歷父級(jí)節(jié)點(diǎn)
parentPath && visitor.BinaryExpression.call(this, parentPath);
}

到這里,我們就得出了結(jié)果 const result = 15;

那么其他運(yùn)算呢:

const result = 100 + 10 - 50 >>> const result = 60;
const result = (100 / 2) + 50 >>> const result = 100;
const result = (((100 / 2) + 50 * 2) / 50) ** 2 >>> const result = 9;

完結(jié)

到這里,已經(jīng)向你大概的講解了,如何編寫一個(gè)Babel插件,再也不怕面試官問我答不出什么了哈...

你以為這就完了嗎?

并沒有

如果轉(zhuǎn)換這樣呢: const result = 0.1 + 0.2;

預(yù)期肯定是0.3, 但是實(shí)際上,Javascript有浮點(diǎn)計(jì)算誤差,得出的結(jié)果是0.30000000000000004

那是不是這個(gè)插件就沒卵用?

這就需要你去矯正浮點(diǎn)運(yùn)算誤差了,可以使用Big.js; 比如: result = node.left.value + node.right.value; 改成 result = +new Big(node.left.value).plus(node.right.value);你以為完了嗎? 這個(gè)插件還可以做很多

比如: Math.PI * 2 >>> 6.283185307179586
比如: Math.pow(2, 2) >>> 4
...
...

優(yōu)化

有旁友指出:

parentPath那一塊可以換個(gè)實(shí)現(xiàn)方法。第一個(gè)binaryExpression真正被計(jì)算之后是會(huì)被替換成numericLiteral的。由于每個(gè)node都會(huì)被visit兩次,所以在exit訪問時(shí),對(duì)于父節(jié)點(diǎn)而言兩個(gè)子節(jié)點(diǎn)又同時(shí)是numericLiteral了,再次執(zhí)行即可。

也就是說,只要在enter和exit節(jié)點(diǎn)的時(shí)候,都執(zhí)行一下上面替換節(jié)點(diǎn)的代碼就行,無須手動(dòng)遍歷父節(jié)點(diǎn)去計(jì)算并替換~

BinaryExpression: {
exit: path => {
const node = path.node;
const result = node.left.value + node.right.value
path.replaceWith(t.numericLiteral(result));
}
}

真是個(gè)不錯(cuò)的方法呢!

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2022-08-02 06:31:32

Java并發(fā)工具類

2022-07-26 08:40:42

Java并發(fā)工具類

2022-06-30 08:14:05

Java阻塞隊(duì)列

2022-07-11 10:47:46

容器JAVA

2024-09-03 07:58:46

2022-06-10 13:56:42

Java

2022-06-30 14:31:57

Java阻塞隊(duì)列

2020-09-26 22:04:32

數(shù)據(jù)安全傳輸HTTPSHTTP 協(xié)議

2024-09-09 08:30:56

代碼

2022-06-08 13:54:23

指令重排Java

2022-06-15 15:14:17

Java公平鎖非公平鎖

2022-06-09 11:20:44

volatile關(guān)鍵字

2021-04-12 21:34:29

Redis故障數(shù)據(jù)

2022-06-24 06:43:57

線程池線程復(fù)用

2023-11-10 08:44:13

分布式鎖分布式系統(tǒng)

2023-09-26 00:37:38

Spring微服務(wù)框架

2021-09-01 07:21:41

面試官開發(fā)讀寫鎖

2020-10-08 14:15:15

Zookeeper

2020-06-17 21:22:56

Serverless面試官架構(gòu)

2019-12-25 11:22:19

負(fù)載均衡集群算法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲一区三区视频在线观看| 精品一二三四五区| 精品电影一区二区| 碰碰在线视频| 亚洲色图校园春色| 日日噜噜噜夜夜爽爽狠狠| 成人在线爆射| 不卡视频一区| 国产不卡一区二区在线播放| 亚洲国产日韩在线一区模特| 奇米影视7777精品一区二区| 麻豆精品久久| 懂色av一区二区夜夜嗨| 欧美视频在线观看免费| 成人app下载| 国产黄在线播放| 在线看三级网站视频| 久久青草精品视频免费观看| 一区二区三区毛片| 亚洲人成7777| 成人黄在线观看| 成人18视频在线播放| 大片免费在线看视频| 不卡一区二区三区视频| 好吊色欧美一区二区三区四区 | 国产丝袜高跟一区| 亚洲国产裸拍裸体视频在线观看乱了中文 | www.午夜色| 国产成人拍精品视频午夜网站| 91黄色免费看| 日韩精品欧美激情一区二区| 日本中文视频| 粉嫩精品一区二区三区在线观看| 欧美日韩国产一区| 国产精品免费看| 欧美天堂影院| www.成人影院| 白白色在线发布| 日本中文视频| 深夜宅男网站免费进入| 免费福利视频一区二区三区| 91久久精品国产91久久性色tv| 狠狠操狠狠色综合网| 在线播放一区| 手机在线免费av| 精品国产av无码一区二区三区| 久久精品国产亚洲精品| 国产欧美日韩在线| 色呦哟—国产精品| 日本网站在线免费观看视频| 日本在线播放不卡| 最好看的2019年中文视频 | 男人天堂a在线| 久久艳片www.17c.com| 国产精品情趣视频| 久久久久久久久久久妇女| 激情视频在线观看| 日韩国产一级片| 日韩美女视频中文字幕| 欧美剧情片在线观看| 成人午夜在线视频| 日韩综合网站| 97久久人人超碰caoprom| 无码中文字幕色专区| 国产精彩精品视频| 日韩午夜激情电影| 国产欧美精品一区二区三区四区 | 各处沟厕大尺度偷拍女厕嘘嘘| 国模私拍一区二区三区| 一本到不卡精品视频在线观看| 免费不卡在线观看| 林ゆな中文字幕一区二区| 3p在线观看| aa在线免费观看| 国产高清精品一区二区| 色多多国产成人永久免费网站 | 亚洲人成网亚洲欧洲无码| 香蕉视频免费在线播放| 欧美 丝袜 自拍 制服 另类| 国产日韩欧美自拍| 亚洲视频一区二区三区| 一区二区三区在线视频免费观看| 亚洲深夜福利| 岛国精品一区| 米奇精品一区二区三区| 国产免费人做人爱午夜视频| 国产精品日韩欧美一区二区三区| 日韩在线视频中文字幕| 色婷婷av一区二区三区之一色屋| 成人手机在线视频| 欧美日韩成人| 亚洲精品一二三**| 久cao在线| 国产黄色片大全| 永久免费网站视频在线观看| 91免费精品视频| 精品激情国产视频| 福利写真视频网站在线| 日韩av电影在线网| 精品日韩av一区二区| 亚洲欧洲成人精品av97| 日韩成人伦理电影在线观看| 亚洲精品动态| 精品欧美一区二区三区在线观看 | 日本在线视频不卡| 国产精品久久久久三级| 欧美人与性动xxxx| 欧美一区二区三区视频免费| 51精品在线观看| 99在线精品观看| 欧美精品在线看| 欧美国产精品日韩| 91a在线视频| 国产一区激情在线| 久久密一区二区三区| 欧美日韩亚洲国产| 成年人在线观看视频| 亚洲黄色小视频在线观看| 亚洲国产成人不卡| 国产日韩亚洲欧美| 久久91亚洲精品中文字幕奶水| 欧美大片在线观看一区| 亚洲h动漫在线| 国产片一区二区| 国产黄色精品视频| 亚洲一区国产| 91成人国产| 亚洲人挤奶视频| 欧美一级做a| 特黄毛片在线观看| 国产三区在线观看| 暖暖视频在线免费观看| 欧美1819sex性处18免费| 蜜桃网站在线观看| 日本成人三级电影网站| 97自拍视频| 国产精品欧美一区二区| 欧美激情第1页| www.色综合| 亚洲精品一区中文字幕乱码| 欧美一级在线免费| 欧美性猛交xxxxxxxx| 精品久久久中文| 亚洲午夜电影网| 一区二区三区不卡视频在线观看 | 日韩精品极品在线观看播放免费视频| 欧美午夜不卡在线观看免费| 精品国产乱码久久久久久天美 | 97国产一区二区精品久久呦 | 激情五月婷婷久久| 91精品国产欧美一区二区成人| 亚洲欧洲三级电影| 国产视频视频一区| 99精品一区二区| 成人免费看视频| 成人高清视频免费观看| 97影院秋霞午夜在线观看| 欧美午夜电影在线观看| 亚洲一区二区在线免费观看视频| 精品国产自在久精品国产| 亚洲日本中文字幕| 91香蕉电影院| 在线视频中文字幕久| av永久不卡| 欧美日韩亚洲国产综合| 日本xxxxx18| 亚洲动漫在线观看| 欧美精品18videosex性欧美| 手机在线免费av| 久久先锋资源网| 国产一区二区三区四区五区在线| av日韩精品| 精品成人一区二区三区| 最色在线观看| 久久精品免费在线观看| 国产高清自拍一区| 国产精品亚洲d| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 午夜精品视频网站| 无码人妻丰满熟妇区毛片| 亚洲一级电影| 中文字幕欧美精品在线| 一级视频在线免费观看| 91精品在线免费观看| 综合毛片免费视频| 欧美高清精品3d| 成人av影视| 日本不卡免费在线视频| 国产日本欧美一区| 日本一区二区三区中文字幕| 精品高清美女精品国产区| 曰本人一级毛片免费完整视频| 漂亮人妻被中出中文字幕| 午夜久久久精品| 中文产幕区在线观看| 成人在线影视| 日本在线精品| 黄色美女久久久| 欧美日韩一区二区高清| 免费观看在线色综合|