¿Los prototipos de Javascript tienen algo equivalente al __index & amp; de Lua? __nuevo índice?
-
10-07-2019 - |
Pregunta
Quiero definir un comportamiento en los objetos Javascript que se activa cuando el atributo / método al que se hace referencia no existe.
En Lua puedes hacer esto con metatables y el __index & amp; __newindex
métodos.
--Lua code
o = setmetatable({},{__index=function(self,key)
print("tried to undefined key",key)
return nil
end
})
Entonces me pregunto si hay algo similar en javascript.
Lo que intento lograr es una interfaz RPC genérica que funcione de esta manera (Javascript no válido):
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");
proxy.ServerMethodA(1,2,3);
proxy.ServerMethodB("abc");
Entonces, ¿cómo puedo hacer esto?
¿Se puede hacer esto?
Solución
javascript se parece más a un esquema que a smalltalk (que admite el método no definido) o lua. Lamentablemente, su solicitud no es compatible, según mi leal saber y entender.
Puede emular este comportamiento con un paso adicional.
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); };
}
}
para que su ejemplo se convierta
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");
podría implementarse más funcionalidad en CAD, pero esto le da la idea ... incluso podría usarlo como un mecanismo de llamada que llama a la función con argumentos si existe, sin pasar por el paso adicional que introduje.
Otros consejos
Solo para su información: Firefox admite un __noSuchMethod__ no estándar
extensión.
Supongo que su necesidad real es más complicada que el ejemplo, porque no está haciendo nada con los parámetros que está pasando a ServerMethodA
y ServerMethodB
, y de lo contrario usted simplemente haría algo como
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");
preguntó hace 8 años, 8 meses
Ahora podemos usar 'Proxy'
Una forma simple de usar:
--Código Lua
local o = setmetatable({},{__index=function(self,key)
print("tried to undefined key",key)
return nil
end
// Con Proxy en 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);
}
})
get: __index
conjunto: __newindex
Reflect.get: rawget
Reflect.set: rawset
en la consola:
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