2009-06-15 84 views
35

长话短说:我处于一种需要PHP样式getter的情况,但在JavaScript中。所有属性的JavaScript getter

我的JavaScript只在Firefox中运行,所以Mozilla特定的JS对我来说可以。

我可以找到一个JS getter的唯一方法是需要指定它的名字,但是我想为定义一个getter,所有可能的名字。我不确定这是否可行,但我很想知道。

+6

我想象他是指魔术功能__get和__ – seanmonstar 2009-06-15 01:39:37

回答

44

最接近你可以找到的是__noSuchMethod__,它等于PHP的__call()。

不幸的是,没有相当于__get/__设置,这是一个耻辱,因为有了它们,我们可以实现__noSuchMethod__,但我还没有看到使用__noSuchMethod__实现属性的方式(如在C#中)。

var foo = { 
    __noSuchMethod__ : function(id, args) { 
     alert(id); 
     alert(args); 
    } 
}; 

foo.bar(1, 2); 
+1

我实际上是在试图创建一个“消息吃零”的等价物,而这正是它*完全*!谢谢! – arantius 2009-06-16 01:36:46

+0

我不知道“消息吃零”的概念。谢谢 – 2009-06-16 05:33:49

+0

nowjs呢?他们必须使用某种类似__set()和__get()等同于使其RPC样式框架真正起作用。我无法从源代码中知道它是如何工作的。 – BMiner 2011-08-08 16:34:02

1

如果你正在寻找类似PHP的__get()函数,我不认为Javascript提供了这样的构造。

我能想到的最好的方法是循环对象的非函数成员,然后为每个成员创建相应的“getXYZ()”函数。

在狡猾的伪代码杂交:

for (o in this) { 
    if (this.hasOwnProperty(o)) { 
     this['get_' + o] = function() { 
      // return this.o -- but you'll need to create a closure to 
      // keep the correct reference to "o" 
     }; 
    } 
} 
5

Javascript 1.5确实有getter/settersyntactic sugar。这是非常好的解释,约翰Resig here

它不是通用的网络使用,但肯定是Firefox有他们(也犀牛,如果你曾经想在服务器端使用它)。

+5

不完全__get()和__set()。 PHP的版本让你监视所有属性,甚至还没有创建。 – BMiner 2011-08-08 16:25:15

5

如果你真的需要工作的实现,你可以通过测试的第二个参数对undefined“欺骗”自己的方式以防万一,这也意味着你可以使用得到实际设置参数。

var foo = { 
    args: {}, 

    __noSuchMethod__ : function(id, args) { 
     if(args === undefined) { 
      return this.args[id] === undefined ? this[id] : this.args[id] 
     } 

     if(this[id] === undefined) { 
      this.args[id] = args; 
     } else { 
      this[id] = args; 
     } 
    } 
}; 
1

我最终使用nickfs的答案来构建自己的解决方案。我的解决方案将自动为所有属性创建get_ {propname}和set_ {propname}函数。在添加它之前,它会检查函数是否已经存在。这允许您使用我们自己的实现覆盖默认的get或set方法,而不会被覆盖的风险。

for (o in this) { 
     if (this.hasOwnProperty(o)) { 
      var creategetter = (typeof this['get_' + o] !== 'function'); 
      var createsetter = (typeof this['set_' + o] !== 'function'); 
      (function() { 
       var propname = o; 
       if (creategetter) { 
        self['get_' + propname] = function() { 
         return self[propname]; 
        }; 
       } 
       if (createsetter) { 
        self['set_' + propname] = function (val) { 
         self[propname] = val; 
        }; 
       } 
      })(); 
     } 
    } 
32

Proxy可以做到这一点!我很高兴这存在!答案在这里给出:Is there a javascript equivalent of python's __getattr__ method?。用我自己的话来改述:

var x = new Proxy({},{get(target,name) { 
    return "Its hilarious you think I have "+name 
}}) 

console.log(x.hair) // logs: "Its hilarious you think I have hair" 

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

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

13

如果您在ES6编码你可以结合代理和类有一个像PHP一个好看代码:

class Magic { 
    constructor() { 
     return new Proxy(this, this); 
    } 
    get (target, prop) { 
     return this[prop] || 'MAGIC'; 
    } 
} 

这种结合的处理程序,所以你可以用它来代替目标。

注意:与PHP不同,代理处理所有的属性请求。

let magic = new Magic(); 
magic.foo = 'NOT MAGIC'; 
console.log(magic.foo); // NOT MAGIC 
console.log(magic.bar); // MAGIC 

您可以检查哪些浏览器支持代理http://caniuse.com/#feat=proxyhttp://caniuse.com/#feat=es6-class类。节点8同时支持。

相关问题