有没有一种方法可以重载以处理JavaScript中的未定义属性?

时间:2010-02-26 19:46:08

标签: javascript

我正在寻找一种方法来处理JavaScript中未定义的方法和属性的调用。

这些类似于PHP魔术方法__call,__ callStatic,__ get。

使用此代码的示例可能是:

var myObject = {};
myObject.__call = function (called, args) {
    alert(called);
    alert(args);
    return(true);
}

myObject.meow("kitty", "miau");

这将导致第一个警告对话框显示“喵”,第二个显示“kitty,miau”。

5 个答案:

答案 0 :(得分:5)

Proxy可以做到!代理可以做一切!这里给出了答案:Is there a javascript equivalent of python's __getattr__ method?。用我自己的话来改写:

var myObject = new Proxy({},{get(target,name) {
  return function() {
    alert(name)
    console.log(arguments) // alerts are bleh
    return true
  }
}})

myObject.meow("kitty", "miau") // alerts "meow", logs ["kitty","miau"] to the console, and returns true

查看MDN文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

适用于chrome,firefox和node.js.缺点:在IE中不起作用 - freakin IE。很快。

答案 1 :(得分:0)

如果您只想要PHP的功能,请阅读我提出的以下解决方案。我假设你将把这个功能放在你自己的对象上。好吧,只要它们不是函数,为方便起见,您可以使用以下约定,它应该适用于所有浏览器:

而不是myobj.foo或myobj ['foo'],只需使用myobj('foo'),并在定义时使对象可调用。但是你必须避免使用“new”,因为“new”永远不能在Javascript中返回一个函数。

var NewFlexible = function() {
  var custom = {};
  return function(prop) {
    if (!(prop in custom)) custom.prop = null;
    return custom.prop;
  };
};

然后你可以像这样创建对象:

myObj = NewFlexible();

使用与Douglas Crockford模式类似的东西,你可以创建扩展它的“类”:

var NewDerived = function(options) {
  var result = {};
  NewFlexible.apply(result, arguments); // parent constructor
  // go on to do what you have to do
  return result;
};

或者,忘记构造函数,你可以只为对象创建一个包装器:

var MakeFlexible = function (obj) { 
 return function(prop) { 
   if ('prop' in obj) return obj.prop; 
   obj.prop = null; return obj.prop;
 };
}

您只需要为代码的所有用户发布此文档。通过这种约定公开你的功能实际上是好的,因为你不想通过使用非标准的javascript来吓跑人们。

答案 2 :(得分:-1)

Javascript中有一个名为__noSuchMethod__的魔术函数。这是一个例子:

var foo = { __noSuchMethod__ : function(name,params) { alert('invalid function call'); } }
foo.bar();

编辑:正如@jldupont所提到的,这实际上只是在Rhino和SpiderMonkey(Mozilla的JS引擎)中; ECMAScript标准不支持它。有一些请求是在ECMAScript 4中。

答案 3 :(得分:-1)

我应该为仍在寻找解决方案的人添加,有:

var myObject = {};
myObject['dynamicMethod'] = new function (parameters) {
    alert(parameters);
};

这里唯一的区别是你可能需要迭代你想要添加的内容。这是预先生成方法,而不是简单地动态处理它们。

答案 4 :(得分:-1)

如果你正在寻找一种方法,你将不得不等到ES7,因为看起来他们不会以这种方式包含它,无论如何,目前有一个工作标准的功能, -in object Proxy,在ES6中添加,我在this question中写了一个答案,以更广泛的方式解决问题。 基本上涉及将对象包装到代理中,加载处理程序

get: function(obj, propname) {custom handling}

进入代理服务器构建器,处理,过滤或实现所有请求属性。

它增加了更多功能......如需完整答案,请进入链接。