如何使用 ECMAScript 5 定义默认的 getter 和 setter?

发布于 2024-09-07 02:17:42 字数 152 浏览 13 评论 0原文

如何为原型指定默认 getter? 对于默认 getter,我的意思是在调用 obj.undefinedProperty123 时调用的函数。

我尝试了 Object.prototype.get = function(property) {..} 但在这种情况下不会调用它。

How can I specify a default getter for a prototype?
With default getter I mean a function that is called if obj.undefinedProperty123 is called.

I tried Object.prototype.get = function(property) {..} but this is not called in this case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

你在看孤独的风景 2024-09-14 02:17:43

您想要创建一个代理

const data = {};

const proxy = new Proxy(data, {
  get: (target, prop) => {
    console.log({ target, prop });
    return "My Value";
  },
  set: (target, prop, value) => {
    console.log({ target, prop, value });
    return true;
  },
});

proxy["foo"] = "bar";
const bar = proxy["foo"];

You want to create a Proxy:

const data = {};

const proxy = new Proxy(data, {
  get: (target, prop) => {
    console.log({ target, prop });
    return "My Value";
  },
  set: (target, prop, value) => {
    console.log({ target, prop, value });
    return true;
  },
});

proxy["foo"] = "bar";
const bar = proxy["foo"];
丘比特射中我 2024-09-14 02:17:43

Firefox 可以使用非标准的 noSuchMethod:-

({__noSuchMethod__:function(){alert(1);}}).a();

Firefox it's possible with non-standard noSuchMethod:-

({__noSuchMethod__:function(){alert(1);}}).a();
携余温的黄昏 2024-09-14 02:17:43

我不确定你在问什么。但是,如果您希望在用户尝试访问 object.nonExistingProperty 时调用一个方法。我认为没有任何办法可以做到这一点。

I am not sure about what you are asking. But If you want a method to be called when the user attempts to Access object.nonExistingProperty . I dont think there is any way to do that.

明月松间行 2024-09-14 02:17:43

也许晚了,让我们添加简单的 ES5 友好的“类创建”:字符串 props 和 getter - 我需要它进行一些古老的重写,暂时支持 IE(是的,这很痛苦,仍然发现有人依赖 ActiveX)

var MyObj = function () {
  var obj = {
    url: 'aabbcc',
    a: function(){ return this.url;}
  }  
  Object.defineProperty(obj, "urltoo", { get: function () { return this.url; } })
  return obj;
}

var X = new MyObj();
x.url // aabbcc
x.urltoo // aabbcc
x.urltoo() // error - not a function
x.a() // aabbcc
x.a // ƒ (){ return this.url;}

maybe late to ther party, let just add simple ES5 friendly "class creation": both string props and getters - i needed it for some ancient rewrite, to temporarily support IE (yes, that hurts, still found someone relying on ActiveX)

var MyObj = function () {
  var obj = {
    url: 'aabbcc',
    a: function(){ return this.url;}
  }  
  Object.defineProperty(obj, "urltoo", { get: function () { return this.url; } })
  return obj;
}

var X = new MyObj();
x.url // aabbcc
x.urltoo // aabbcc
x.urltoo() // error - not a function
x.a() // aabbcc
x.a // ƒ (){ return this.url;}
心清如水 2024-09-14 02:17:43

我遇到这个问题是因为我想要这种行为:如果对象属性未定义,则返回一些默认值。

const options = {
  foo: 'foo',
  bar: 'bar',
  baz: 'baz'
};

function useOptionValue(optionName) {
  // I want `options` to return a default value if `optionName` does not exist
  const value = options[optionName];
  // etc...
}

执行此操作的简单方法(对于此用例没有 Proxy 或 Object.defineProperty 过度杀伤力)如下所示:

function useOptionValue(optionName) {
  const value = options[optionName] || defaultValue;
}

或者,如果您想变得更奇特,您可以使用 符号

const default = Symbol.for('default');

const options = {
  foo: 'foo',
  bar: 'bar',
  baz: 'baz',
  [default]: 'foobarbaz'
};

function useOptionValue(optionName) {
  const value = options[optionName] || options[default];
}

I ran into this question because I wanted this behavior: if object property is undefined, return some default value instead.

const options = {
  foo: 'foo',
  bar: 'bar',
  baz: 'baz'
};

function useOptionValue(optionName) {
  // I want `options` to return a default value if `optionName` does not exist
  const value = options[optionName];
  // etc...
}

The simple way to do this (without Proxy or Object.defineProperty overkill for this use case) is like so:

function useOptionValue(optionName) {
  const value = options[optionName] || defaultValue;
}

Or, if you want to get fancy, you could use a Symbol:

const default = Symbol.for('default');

const options = {
  foo: 'foo',
  bar: 'bar',
  baz: 'baz',
  [default]: 'foobarbaz'
};

function useOptionValue(optionName) {
  const value = options[optionName] || options[default];
}
污味仙女 2024-09-14 02:17:42

在 ECMAScript 5 中,您只能通过 Object.defineProperty

Object.defineProperty(someObj, "someProp", {
    get: function() {
        console.log("you tried to get someObj.someProp");
        return "foo";
    }
});

在这里,get 函数将在代码尝试读取 时运行someObj.someProp

在即将发布的 ECMAScript 6 草案中,这将可以通过 代理实现。代理具有底层目标对象和设置/获取函数。每当对代理的任何属性进行设置或获取操作时,都会运行适当的函数,并将代理的目标对象、使用的属性名称以及 set 尝试中使用的值作为参数。

var proxyHandler = {
    get: function(obj, name){
        console.log("you're getting property " + name);
        return target[name];
    },
    set: function(obj, name, value) {
        console.log("you're setting property " + name);
        target[name] = value;
    }
}

var underlyingObj = {};

// use prox instead of underlyingObj to use get/set interceptor functions
var prox = new Proxy(underlyingObj, proxyHandler);

在这里,设置为获取 prox 上的属性值将导致 set/get 函数运行。

In ECMAScript 5, you can only intercept get/set operations on specific named properties (not universally all properties) via Object.defineProperty:

Object.defineProperty(someObj, "someProp", {
    get: function() {
        console.log("you tried to get someObj.someProp");
        return "foo";
    }
});

Here, the get function will run any time code tries to read someObj.someProp.

In the upcoming ECMAScript 6 draft, this will be possible via proxies. A proxy has an underlying target object and set/get functions. Any time a set or get operation happens on any of a proxy's properties, the appropriate function runs, taking as arguments the proxy's target object, property name used, and the value used in a set attempt.

var proxyHandler = {
    get: function(obj, name){
        console.log("you're getting property " + name);
        return target[name];
    },
    set: function(obj, name, value) {
        console.log("you're setting property " + name);
        target[name] = value;
    }
}

var underlyingObj = {};

// use prox instead of underlyingObj to use get/set interceptor functions
var prox = new Proxy(underlyingObj, proxyHandler);

Here, setting to getting property values on prox will cause the set/get functions to run.

尬尬 2024-09-14 02:17:42

Gareth 所说的,只不过是 __noSuchMethod__

或者也许您正在考虑 PHP?

这是一篇关于最近标准化的属性 getter/setter 的非常好的文章,重点介绍了一些以前的非标准化身。

http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and -setters-is-being-removed/

摘要:目前还没有标准的“包罗万象”的 getter/setter,但 Object.defineProperty 是未来。

What Gareth said, except it's __noSuchMethod__.

Or maybe you were thinking of PHP?

Here's a very good article on the recently standardized property getters/setters, highlighting some previous non-standard incarnations.

http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/

summary: there's no standard 'catch-all' getter / setter (yet), but Object.defineProperty is the future.

与酒说心事 2024-09-14 02:17:42

您需要等待 ECMA6“代理”系统的实施,该系统正是为此而设计的。请参阅 http://wiki.ecmascript.org/doku.php?id=harmony: direct_proxys

You need to wait for the implementation of the ECMA6 "Proxy" system, designed to do exactly this. See http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文