Lua元表使用 __index和__newindex方法有点类似get和set方法,可以利用这个特性实现监听table的属性变化。
- table.key = value 只有在table中不存在该key时才会走元表的__newindex方法。
可以对 Lua实现继承 中的Object做一层封装,返回一个空表,外界对这个空表的所有访问和设置都要通过元表的__index和__newindex方法,从而实现监听。
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方法里返回了一个空表,用Observable:new()创建 而没有用__call,也可以将__call改造成new方法返回实例对象。