¿Los prototipos de Javascript tienen algo equivalente al __index & amp; de Lua? __nuevo índice?

StackOverflow https://stackoverflow.com/questions/1642167

  •  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?

¿Fue útil?

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'

Proxy - JavaScript | MDN

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top