У прототипов Javascript есть что-то, эквивалентное Lua __index & amp; __newindex?

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

  •  10-07-2019
  •  | 
  •  

Вопрос

Я хочу определить поведение объектов Javascript, которое срабатывает, когда указанный атрибут / метод не существует. В Lua это можно сделать с помощью метатаблиц и индекса __ & amp; __newindex методы.

--Lua code
o = setmetatable({},{__index=function(self,key)
  print("tried to undefined key",key)
  return nil
end
})

Поэтому мне интересно, есть ли что-то похожее в javascript.

Я пытаюсь добиться универсального интерфейса RPC, который работает следующим образом (недопустимый Javascript):

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");

Так как я могу это сделать?

Можно ли это сделать?

Это было полезно?

Решение

JavaScript больше похож на схему, чем на 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");

можно было бы реализовать больше функций в САПР, но это дает вам идею ... вы даже можете использовать его в качестве механизма вызова, который вызывает функцию с аргументами, если она существует, минуя дополнительный шаг, который я представил.

Другие советы

Просто к сведению: Firefox поддерживает нестандартный __shochet расширение.

Я предполагаю, что ваши реальные потребности сложнее, чем в примере, потому что вы ничего не делаете с параметрами, которые вы передаете в 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");
  

спросил 8 лет, 8 месяцев назад

Теперь мы можем использовать «Прокси»

Прокси - JavaScript | MDN

Простой способ использования:

- код Lua

local o = setmetatable({},{__index=function(self,key)
  print("tried to undefined key",key)
  return nil
end

// С прокси в 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

set: __newindex

Reflect.get: rawget

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top