lua中实现类似js Proxy功能

利用lua元表__newindex可以实现数据变化监测,在需要的地方添加数据监听。

local function _createHelper(target)
    local obj = {};
    obj.__setCallbacks__ = {};
    function obj:addObserver(key,callback)
        if key==nil or type(callback)~="function" then
            return
        end
        local arr = self.__setCallbacks__[key]
        if arr==nil then
            self.__setCallbacks__[key] = {}
            arr = self.__setCallbacks__[key]
        end
        arr[#arr+1] = callback
        callback(target[key],nil)
        return #arr
    end

    function obj:removeObserver(key,handlerId)
        if key==nil or type(handlerId)~="number" then
            return
        end
        local arr = self.__setCallbacks__[key]
        if arr==nil then
            return
        end
        arr[handlerId] = nil
    end

    function obj:_exec(key,val,old)
        local arr = self.__setCallbacks__[key] or {}
        for k,v in pairs(arr) do
            if v then
                v(val,old)
            end
        end
    end

    return obj
end


local function createProxy(target)
    local obj = _createHelper(target)

    local handler = {
        set = function(target,key,value,oldValue)
            obj:_exec(key,value,oldValue)
        end,
        get = function(target,key,val)

        end
    }
    
    local ret = setmetatable(obj,{
        __index = function (t,key)
            handler.get(target,key,target[key])
            return target[key]
        end,
        __newindex = function (t,key,val)
            if target[key] then
                local old = target[key]
                target[key] = val
                handler.set(target,key,val,old)
            else
                rawset(t,key,val)
            end
        end
    })
    return ret;
end

return createProxy

测试:

local obj = {
    a = 1,
    b = "hello"
}
local _proxy = createProxy(obj)
local id = _proxy:addObserver("b",function (val,old)
    print("---------1111 ",val,old)
end)
--原始obj对象没有g字段,所以监听无效
local id2 = _proxy:addObserver("g",function (val,old)
    print("---------2222 ",val,old)
end)

_proxy.b = "bbb"
--删除监听后,监测失效
_proxy:removeObserver("b",id)
_proxy.b = "b22"

_proxy.ggg = "ggg"

输出

---------1111   hello   nil
---------2222   nil nil
---------1111   bbb hello
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ![Flask](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW...
    极客学院Wiki阅读 7,269评论 0 3
  • 不知不觉易趣客已经在路上走了快一年了,感觉也该让更多朋友认识知道易趣客,所以就谢了这篇简介,已做创业记事。 易趣客...
    Physher阅读 3,441评论 1 2
  • 双胎妊娠有家族遗传倾向,随母系遗传。有研究表明,如果孕妇本人是双胎之一,她生双胎的机率为1/58;若孕妇的父亲或母...
    邺水芙蓉hibiscus阅读 3,722评论 0 2
  • 晴天,拥抱阳光,拥抱你。雨天,想念雨滴,想念你。 我可以喜欢你吗可以啊 我还可以喜欢你吗可以,可是你要知道我们不可...
    露薇霜凝阅读 1,237评论 1 2