如何看待Vue.js 2.0 的模板編譯使用了`with(this)`的語法?
比如這樣的 Vue 組件
&
&納尼?你再說一次.{{msg}}&
&&
最終會被編譯成這樣的JS
module.exports={render:function (){with(this) { // &<- with return _h("p", { on: { "click": function($event) { alert(123) }, "hee": function($event) { sayHello(msg) } } }, ["納尼?你再說一次." + _s(msg)]) }},staticRenderFns: []}
為啥呢,因為沒有什麼太明顯的壞處(經測試性能影響幾乎可以忽略),但是 with 的作用域和模板的作用域正好契合,可以極大地簡化模板編譯過程。Vue 1.x 使用的正則替換 identifier path 是一個本質上 unsound 的方案,不能涵蓋所有的 edge case;而走正經的 parse 到 AST 的路線會使得編譯器代碼量爆炸。雖然 Vue 2 的編譯器是可以分離的,但凡是可能跑在瀏覽器里的部分,還是要考慮到尺寸問題。用 with 代碼量可以很少,而且把作用域的處理交給 js 引擎來做也更可靠。
用 with 的主要副作用是生成的代碼不能在 strict mode / ES module 中運行,但直接在瀏覽器里編譯的時候因為用了 new Function(),等同於 eval,不受這一點影響。
當然,最理想的情況還是可以把 with 去掉,所以在使用預編譯的時候(vue-loader 或 vueify),會自動把第一遍編譯生成的代碼進行一次額外處理,用完整的 AST 分析來處理作用域,把 with 拿掉,順便支持模板中的 ES2015 語法。也就是說如果用 webpack + vue 的時候,最終生成的代碼是沒有 with 的。
為什麼vue2做了這樣的選擇,請看小右自己的答案。我只是來賣萌的……
其實html里的event handler content attribute也可以認為用了with。比如&
※如何評價台灣人說大陸鋼年產量8萬噸,建一座橋用掉1/4?
※如何評價《美國恐怖故事》第五季?
※如何評價拉文和戈登在 2016 年 NBA 全明星扣籃大賽中的表現?
TAG:前端開發框架和庫 | JavaScript語言精粹 | 如何看待評價X | X編程語言有什麼奇技淫巧 | Vuejs |