js原型鏈與lua元表的異同?

因為之前工作的原因接觸了lua腳本但了解不深,在使用的過程中覺得實際上元表的概念和js中的對象原型鏈很相像,而元表更可以對預置的操作值定義不同的行為。不過也曾經看見知友回答過,原型鏈的功能只及得上元表功能的10%,所以想知道其中別的異同表現在什麼方面。


同:本質上是一樣的。都是附加在Object/table上的一個額外屬性,都可以給Object/table提供一些額外的屬性或功能以滿足動態語言中模仿部分OO特性的需求。

異:我覺得JS的Prototype打一開始就是為了滿足OO而設計的。而Lua的哲學向來是:使用儘可能少的、儘可能簡單的特性,滿足使用上各種擴充特性的需求。在metatable所解決的需求中,OO只是一個方面,而不是全部。所以Lua的metatable的使用上和prototype差別很大。

舉例來說,JS的prototype是綁在構造函數上的,而Lua不是。

這樣帶來的結果是:

1、在JS中實現一個基本的OO要比Lua中容易的多。__getter__ 和__setter__都語法級別的現成的手段。

2、用Lua的元表能夠實現更複雜的OO,還能實現大量傳統OO所不具備的設計模式。 包括但不限於:多重繼承、聚合、代理對象 等等。

另外,因為Lua中到處都是table,所以元表還能用於一些與OO的無關的場合,譬如:使用元表,你可以在任何人試圖創建一個全局變數的時候產生一個警告。(鄙公司用了這樣的手段,防止初級程序員常犯的忘記寫local的錯誤),在5.1的編碼風格(module(..., package.seeall))里,模塊內的代碼可以訪問全局變數也是這樣實現的。

總結: 本質上是一樣的。外在上是差別很大的。JS的prototype更適用於OO而Lua的metatable能滿足更多需求。


JS 的 [[
m Prototype]] 大致相當於 Lua 元表中的 __index 項。


metatable的抽象層次更高,應用範圍更大。而JS的prototype顯然是沖著「合併公用函數」這個目標來的。一個是學院派,一個是工程派


手機碼字,暫發一下,過完年有電腦再詳細答下。lua的元表設計的簡單卻功能強大,最明顯的就是比原型鏈多出可以模擬操作符重載功能。而在兩者都能實現的功能的部分上,原型鏈卻實現得晦澀不堪。元表就一個思想,遇到對錶的操作時,可以允許程序員對此做個類似「掛鉤」的操作。由此你可以重載,可以實現繼承。。。理念單純卻功能強大。而原型雖然差不多,但隨著規範的改進又加了些意料之外的東西,比如構造函數等,很多概念混在裡面。待續。。。。。。


由於沒有用過lua,我稍微 微軟必應搜索 了一下,覺得js和lua在這裡的的最大區別就是,js的對象可以從prototype裡面創建出來,所以當你改了prototype的時候,所有由這個prototype創建的對象在語義上都會自動感應到變化,儘管對象本身的布局並沒有發生變化。而lua的每一個對象之間是沒有任何關聯的。

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

update 大家都說lua有公用的metatable,就不知道為什麼說【原型鏈的功能只及得上元表功能的10%】了,我覺得本質上是可以互相替換的。


Lua 中的 metatable 比 JavaScript 中的 prototype 高級.

JavaScript 中的 Proxy 又擴展了 JavaScript.

感覺比 Lua 中的 Metatable 又高級了.


推薦閱讀:

產品經理如何在設計產品時避免給開發挖坑?
前端開發js函數式編程真實用途體現在哪裡?
怎麼評價Vue.js2.5以後要大力加強對TypeScript和VSCode的支持?
font-weight和fontWeight的區別?
onclick = xxx這種賦值寫法綁定事件的原理是什麼?

TAG:前端開發 | JavaScript | 編程 | Lua |