日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

underscore.js源码研究(5)

發布時間:2023/12/18 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 underscore.js源码研究(5) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

很早就想研究underscore源碼了,雖然underscore.js這個庫有些過時了,但是我還是想學習一下庫的架構,函數式編程以及常用方法的編寫這些方面的內容,又恰好沒什么其它要研究的了,所以就了結研究underscore源碼這一心愿吧。

underscore.js源碼研究(1)
underscore.js源碼研究(2)
underscore.js源碼研究(3)
underscore.js源碼研究(4)
underscore.js源碼研究(5)
underscore.js源碼研究(6)
underscore.js源碼研究(7)
underscore.js源碼研究(8)

參考資料:underscore.js官方注釋,undersercore 源碼分析,undersercore 源碼分析 segmentfault

模板引擎

之前就接觸過模板引擎,比如說template.js、handlebars.js、jade.js、nunjucks.js等等。后來學react的時候也接觸過jsx,當時我就感到很不可思議,竟然能夠把js中的變量甚至語句插入到html里面去,真的十分神奇。今天看underscore.js的源碼的時候也發現里面竟然有模板引擎,于是我就來研究研究模板引擎。

實現變量替換

說到模板引擎,一個最基本的特性就是能在html代碼中插入js的變量,下面我們來實現這種效果。

我們需要實現這種效果:

//定義一個模板 const tpl = 'hello {{name}}';//定義值 const data = {name: 'haha'};//渲染,最后content是name被替換過的html代碼 const output = render(tpl, data);

其實仔細理了一下效果的流程之后,感覺實現這個效果挺簡單的,就是用一個正則替換,把{{ name }}里面的值替換為data里面的數據就行了。

實現代碼如下:

//定義替換的正則表達式 const rule = /{{([\s\S]+?)}}/g;//render函數 function render(tpl, data) {return tpl.replace(rule, (matcher, p1) => {return data[p1];}) }

注意,由于rule里面只有一個括號,所以replace第二個參數的函數里面只有p1沒有p2。

變量替換改進

為了便于閱讀,我們需要模板可以寫成下面的形式。(name兩邊有空格)

//定義一個模板 const tpl = 'hello {{ name }}';

所以我們加一個去空格的函數,整個代碼如下:

//定義替換的正則表達式 const rule = /{{([\s\S]+?)}}/g;//render函數 function render(tpl, data) {return tpl.replace(rule, (matcher, p1) => {return data[p1.trim()];}) }

注意:trim函數只兼容IE9,如果要兼容IE9以下的話就需要pollyfill了。

支持語句

幾乎所有的模板引擎都支持寫入語句,比如像下面的寫法:

const tpl = 'Students:' +//注意這里只有一個大括號!!!'{ for(i = 0; i < data.students.length; i++) }' +'{{ data.students[i].name }}'; const data = {students: [{id: 1,name: ' haha '},{id: 2,name: ' yaya '}] }; const content = render(tpl, data);

我們希望上述代碼輸出:

Students: haha yaya

看起來非常復雜,可是我們用偽代碼分解一下執行過程就感覺有點簡單了:

//首先輸出Students: //然后執行下面的代碼 for(i = 0; i < data.students.length; i++) { //這里輸出students[i].name } //完畢

實際寫起來是這樣的:

//定義要輸出的內容 content = ''; content += 'Students:'; for(i = 0; i < data.students.length; i++) {content += 'data.students[i].name'; } //輸出整個content return content

可以看到,上面有這2個要點:

  • 變量的內容需要添加到content里面,但是語句的內容不需要添加到content里面。
  • 不是模板的內容要記錄位置,然后再通過這個位置添加到content里面。
  • 所以好好整理一下,我們首先需要語句的正則表達式,然后通過這個正則表達式按照上述規則進行替換,代碼如下:

    //為了方便,我們把規則封裝在一個對象里面 const rules = {//插值,對應變量interpolate: /{{([\s\S]+?)}}/,//邏輯,對應語句evaluate: /{([\s\S]+?)}/ }; //2個正則合在一起,先替換變量,再替換語句 const matcher = new RegExp([rules.interpolate.source,rules.evaluate.source ].join('|'), 'g');//render函數 function render(tpl, data) {let concating = 'let content = "";\n';let index = 0;//仍然是replace里面的第二個參數是函數的形式tpl.replace(matcher, (match, interpolate, evaluate, offset) => {//添加非模板的內容if (tpl.slice(index, offset)) {concating += 'content += "' + tpl.slice(index, offset) + '";\n';}//記錄偏移量index = offset + match.length;//變量需要添加到content里面if (interpolate) {concating += 'content +=' + interpolate + ';\n';//語句不需要添加到content里面,而且不要分號} else if (evaluate) {concating += evaluate + '\n';}})concating += 'return content;';//以concating為內容,定義一個函數,參數是objconst renderFunc = new Function('obj', concating);return renderFunc(data); }

    它生成的renderFunc函數的代碼如下圖所示:

    (function(obj /*``*/) { let content = ""; content += "Students:";for(i = 0; i < data.students.length; i++) content += data.students[i].name ; return content; })

    可以看到有一個缺點,就是for循環沒有大括號,這就導致它只執行下面的那條語句。如果要加大括號的話,就需要額外的規則,我們這里不討論。

    所以把上面所有的代碼加起來就是這樣的:

    //為了方便,我們把規則封裝在一個對象里面 const rules = {//插值,對應變量interpolate: /{{([\s\S]+?)}}/,//邏輯,對應語句evaluate: /{([\s\S]+?)}/ };//2個正則合在一起,先替換變量,再替換語句 const matcher = new RegExp([rules.interpolate.source,rules.evaluate.source ].join('|'), 'g');//定義模板和數據 const tpl = 'Students:' +//注意這里只有一個大括號!!!'{ for(i = 0; i < data.students.length; i++) }' +'{{ data.students[i].name }}'; const data = {students: [{id: 1,name: ' haha '},{id: 2,name: ' yaya '}] };//render函數 function render(tpl, data) {let concating = 'let content = "";\n';let index = 0;//仍然是replace里面的第二個參數是函數的形式tpl.replace(matcher, (match, interpolate, evaluate, offset) => {//添加非模板的內容if (tpl.slice(index, offset)) {concating += 'content += "' + tpl.slice(index, offset) + '";\n';}//記錄偏移量index = offset + match.length;//變量需要添加到content里面if (interpolate) {concating += 'content +=' + interpolate + ';\n';//語句不需要添加到content里面,而且不要分號} else if (evaluate) {concating += evaluate + '\n';}})concating += 'return content;';//以concating為內容,定義一個函數,參數是objconst renderFunc = new Function('obj', concating);return renderFunc(data); }//輸出,結果為Students: haha yaya console.log(render(tpl, data));

    可以看到,整個過程實際上是在拼接和替換字符串,然后利用Function接受字符串的情形生成函數,沒有其他的任何內容。

    在下一篇博文中我們會對這個小的模板引擎進行優化。

    轉載于:https://www.cnblogs.com/yangzhou33/p/8972394.html

    總結

    以上是生活随笔為你收集整理的underscore.js源码研究(5)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: a毛片大片| 中日韩在线观看视频 | 欧美少妇毛茸茸 | 欧美精品久久久久 | xxx69美国 | 久久亚洲AV无码专区成人国产 | 欧美无吗| 亚洲图片欧美在线 | 亚洲午夜精品 | 99精品在线视频观看 | 蜜桃成人免费视频 | 欧美 日韩 高清 | 亚洲videos| 禁久久精品乱码 | 国产污污 | 中文字幕乱码免费 | 亚洲国产日韩一区 | 热の国产 | 涩天堂 | 免费成人av网址 | 欧美人与性禽动交精品 | 成人欧美一区二区三区在线播放 | 青娱网电信一区电信二区电信三区 | 亚洲精品国产成人久久av盗摄 | 青草视频免费在线观看 | 99久久精品免费看国产四区 | 久久天天躁狠狠躁夜夜av | 午夜婷婷色 | 免费看国产曰批40分钟粉红裤头 | 国产乱码精品一区二区三区不卡 | av综合久久 | 亚洲狼人综合 | 意大利少妇愉情理伦片 | 久久国产成人 | 日韩国产亚洲欧美 | 国产精品老熟女一区二区 | 国产不卡一区二区视频 | 超碰1000| 少妇高潮一区二区三区99刮毛 | 麻豆网站在线免费观看 | 中文字幕乱伦视频 | 精品少妇一区二区三区免费观 | 精品动漫一区二区 | 亚洲一区二区三区电影在线观看 | 一亲二脱三插 | 神马午夜一区二区 | 美女主播在线观看 | 成人性视频网 | 久久99久久精品 | 全部免费毛片在线播放一个 | 女攻总攻大胸奶汁(高h) | 成人av一区二区三区在线观看 | 91影院在线观看 | 先锋影视av | 亚洲素人在线 | 日本一级做a爱片 | 免费在线视频你懂的 | 中文字幕23 | 成人天堂 | 久久婷婷国产麻豆91天堂 | 91免费版在线看 | 色播视频在线观看 | 欧美自拍一区 | 欧美草比视频 | 少妇高潮毛片色欲ava片 | 午夜亚洲av永久无码精品 | 亚色视频在线观看 | jizz成熟丰满老女人 | 国产男男gay | 日本天堂网在线 | 女人一区二区 | 高潮白浆 | 国产精品久久久久久久av福利 | 双腿张开被9个男人调教 | 久久中文视频 | 国产熟妇一区二区三区四区 | 一级免费看片 | 国产精品久久综合青草亚洲AV | 久久久久久亚洲 | 五月花婷婷 | 国产成人综合亚洲 | 人妻精品无码一区二区三区 | 性生交大片免费看狂欲 | 成人日韩欧美 | 伊人久久大香线 | 欧美日韩人妻精品一区二区三区 | 亚洲人成影视 | 亚洲乱论 | 欧美一区二区三区的 | 啄木乌欧美一区二区三区 | 欧美a级免费 | 国产欧美日 | 色美av| 国产黄色a| 冲田杏梨一区二区三区 | 超碰公开在线观看 | 三级网站在线 | 亚洲一区和二区 | 国产一级做a爰片久久毛片男 |