Lua元表使用 __index和__newindex方法有點(diǎn)類(lèi)似get和set方法示姿,可以利用這個(gè)特性實(shí)現(xiàn)監(jiān)聽(tīng)table的屬性變化杠人。
- table.key = value 只有在table中不存在該key時(shí)才會(huì)走元表的__newindex方法于游。
可以對(duì) Lua實(shí)現(xiàn)繼承 中的Object做一層封裝,返回一個(gè)空表惋增,外界對(duì)這個(gè)空表的所有訪問(wèn)和設(shè)置都要通過(guò)元表的__index和__newindex方法阎肝,從而實(shí)現(xiàn)監(jiān)聽(tīng)。
local Observable = Object:extend()
function Observable:new()
Observable.super.new(self)
return self:_observable()
end
function Observable:_observable()
self.observKeys = {}
self.__observable_table = setmetatable({}, {
__index = self,
__newindex = function(t, k, v)
print("VALUE CHANGE~ "..k.."=== old(",self[k],") new(",v,")")
local callback = self.observKeys[k]
if type(callback) == "function" then
callback(self[k], v)
end
self[k] = v
end,
__pairs = function (t) return pairs(self) end,
__ipairs = function (t) return ipairs(self) end,
__len = function (t) return #self end
})
return self.__observable_table
end
local a = Observable:new()
a.v2 = {} -- VALUE CHANGE~ V2 === old( nil ) new( table:0x281ab19c0 )
a.v2 = "123" -- VALUE CHANGE~ V2 === old( table:0x281ab19c0 ) new( 123 )
ps. 這里在new方法里返回了一個(gè)空表窗市,用Observable:new()創(chuàng)建 而沒(méi)有用__call先慷,也可以將__call改造成new方法返回實(shí)例對(duì)象。