76

长话短说:我现在想要一个 PHP 风格的 getter,但在 JavaScript 中。

我的 JavaScript 仅在 Firefox 中运行,因此我可以使用 Mozilla 特定的 JS。

我能找到制作 JS getter 的唯一方法需要指定它的名称,但我想为所有可能的名称定义一个 getter。我不确定这是否可能,但我非常想知道。

4

9 回答 9

100

Proxy可以做到!我很高兴这存在!这里给出了一个答案:是否有与 python 的 __getattr__ 方法等效的 javascript?. 用我自己的话说:

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 中不起作用 - 该死的 IE。很快。

于 2016-03-20T07:35:17.323 回答
55

你可以将代理和类结合起来,得到一个漂亮的代码,比如 php

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

this 绑定到处理程序,因此您可以使用 this 而不是 target。

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

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

您可以查看哪些浏览器支持代理http://caniuse.com/#feat=proxy

于 2017-04-10T12:25:44.107 回答
47

您能找到的最接近的是__noSuchMethod__,它相当于 JavaScript 的 PHP 的 __call()。

不幸的是,没有 __get/__set 等价物,这是一种耻辱,因为我们可以使用它们实现 __noSuchMethod__,但我还没有看到使用 __noSuchMethod__ 实现属性的方法(如在 C# 中)。

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

foo.bar(1, 2);
于 2009-06-15T03:26:36.220 回答
5

Javascript 1.5确实有getter/setter 语法糖John Resig在这里解释得很好

它对于网络使用来说还不够通用,但是 Firefox 肯定有它们(还有 Rhino,如果你想在服务器端使用它)。

于 2009-06-15T02:45:32.403 回答
5

如果你真的需要一个有效的实现,你可以通过测试第二个参数来“欺骗”你的方式undefined,这也意味着你可以使用 get 来实际设置参数。

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;
        }
    }
};
于 2012-10-17T14:52:40.667 回答
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"
        };
    }
}
于 2009-06-15T01:04:09.370 回答
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;
                    };
                }
            })();
        }
    }
于 2014-11-12T21:43:49.513 回答
0

这不完全是对原始问题的回答,但是这个这个问题已关闭并重定向到这里,所以我在这里。我希望我能像我一样帮助其他一些来到这里的 JS 新手。

来自 Python,我正在寻找的是obj.__getattr__(key)obj.__hasattr__(key)方法的等价物。我最终使用的是: obj[key]forgetattrobj.hasOwnProperty(key)for hasattr( doc )。

于 2020-05-19T17:23:58.947 回答
0

只需将对象包装在 getter 函数中即可获得类似的结果:

const getProp = (key) => {
  const dictionary = {
    firstName: 'John',
    lastName: 'Doe',
    age: 42,
    DEFAULT: 'there is no prop like this'
  }
  return (typeof dictionary[key] === 'undefined' ? dictionary.DEFAULT : dictionary[key]);
}

console.log(getProp('age')) // 42

console.log(getProp('Hello World')) // 'there is no prop like this'

于 2021-12-07T08:47:43.570 回答