У прототипов Javascript есть что-то, эквивалентное Lua __index & amp; __newindex?
-
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 месяцев назад
Теперь мы можем использовать «Прокси»
Простой способ использования:
- код 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