Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript原型是否具有与Lua';s__指数和__新索引?_Javascript_Prototype_Lua - Fatal编程技术网

Javascript原型是否具有与Lua';s__指数和__新索引?

Javascript原型是否具有与Lua';s__指数和__新索引?,javascript,prototype,lua,Javascript,Prototype,Lua,我想在Javascript对象上定义一个行为,当引用的属性/方法不存在时,该行为将生效。 在Lua中,您可以使用元表和\uuuuu index&\uuuu newindex方法来实现这一点 --Lua code o = setmetatable({},{__index=function(self,key) print("tried to undefined key",key) return nil end }) 所以我想知道javascript中是否有类似的东西 我试图实现的是一个通用

我想在Javascript对象上定义一个行为,当引用的属性/方法不存在时,该行为将生效。 在Lua中,您可以使用元表和
\uuuuu index&\uuuu newindex
方法来实现这一点

--Lua code
o = setmetatable({},{__index=function(self,key)
  print("tried to undefined key",key)
  return nil
end
})
所以我想知道javascript中是否有类似的东西

我试图实现的是一个通用RPC接口,其工作原理如下(不是有效的Javascript):

那我该怎么做呢


甚至可以这样做吗?

我假设您的实际需要比示例更复杂,因为您对传递给
ServerMethodA
ServerMethodB
的参数不做任何操作,否则您只需执行以下操作

function RPC(url)
{
    this.url = url;
}

RPC.prototype.callServerMethod = function(methodname, params)
{ 
    AJAX.get(this.url+"?call="+ methodname);
}

var proxy = RPC("http://example.com/rpcinterface");
proxy.callServerMethod("ServerMethodA", [1,2,3]);
proxy.callServerMethod("ServerMethodB", "abc");

更新:此答案不再正确。ECMAScript 2015(§§9.5,26.2)定义了可用于实现此目的的对象

在不提供代理的JavaScript引擎中,此功能仍然不可用。在这些引擎中,Lua中依赖于
\uuuu index
\uuu newindex
的习惯用法必须以其他方式表达,如下所示


javascript更像scheme,而不是smalltalk(支持未定义的方法)或lua。不幸的是,据我所知,你的请求没有得到支持

您可以通过额外的步骤来模拟这种行为

function CAD(object, methodName) // Check and Attach Default
{
    if (!(object[methodName] && typeof object[methodName] == "function") &&
         (object["__index"] && typeof object["__index"] == "function")) {
        object[methodName] = function() { return object.__index(methodName); };
    }
}
所以你的例子变成了

function RPC(url)
{
    this.url = url;
}

RPC.prototype.__index=function(methodname) //imagine that prototype.__index exists
{ 
    AJAX.get(this.url+"?call="+ methodname);
}

var proxy = RPC("http://example.com/rpcinterface");
CAD(proxy, "ServerMethodA");
proxy.ServerMethodA(1,2,3);
CAD(proxy, "ServerMethodB");
proxy.ServerMethodB("abc");

更多的功能可以在CAD中实现,但这给了您一个想法……您甚至可以将其用作调用机制,在函数存在时使用参数来调用函数,而不必经过我介绍的额外步骤。

仅供参考:Firefox支持非标准扩展

问8年8个月前

现在我们可以使用“代理”

一种简单的使用方法:

--Lua码

//使用Javascript中的代理

let o = new Proxy({}, {
    get: function (target, key, receiver) {
        if (!target.hasOwnProperty(key)){
            console.log("tried to undefined key "+key);
        }
        return Reflect.get(target, key, receiver);
    },
    set: function (target, key, value, receiver) {
        console.log(`set `+ key);
        return Reflect.set(target, key, value, receiver);
    }
})
获取:\索引

集合:uu newindex

反射,反射,反射

Reflect.set:rawset

在控制台中:

let o= new Proxy({},{
    get: function (target, key, receiver) {
            let ret = Reflect.get(target, key, receiver);
            if (!target.hasOwnProperty(key)){
                console.log("tried to undefined key "+key);
            }
            return ret;
        }
})
>> undefined

o.a
>> VM383:5 tried to undefined key a
>> undefined

o.a = 1
>> 1

o.a
>> 1

我有点想象javascript有一个_;索引,我就是找不到,但似乎我错了。谢谢你的信息和技巧。这对我来说已经足够好了!谢谢你的信息,不幸的是,我需要跨浏览器的兼容性,但很高兴知道,也许其他人会跟随套件
let o = new Proxy({}, {
    get: function (target, key, receiver) {
        if (!target.hasOwnProperty(key)){
            console.log("tried to undefined key "+key);
        }
        return Reflect.get(target, key, receiver);
    },
    set: function (target, key, value, receiver) {
        console.log(`set `+ key);
        return Reflect.set(target, key, value, receiver);
    }
})
let o= new Proxy({},{
    get: function (target, key, receiver) {
            let ret = Reflect.get(target, key, receiver);
            if (!target.hasOwnProperty(key)){
                console.log("tried to undefined key "+key);
            }
            return ret;
        }
})
>> undefined

o.a
>> VM383:5 tried to undefined key a
>> undefined

o.a = 1
>> 1

o.a
>> 1