简体   繁体   English

在JavaScript中为动态属性设置

[英]Setter for a dynamic property in javascript

I'm wondering if it's possible to have a setter for a dynamic property in Javascript ? 我想知道是否可以在Javascript中使用动态属性的设置方法?

So this: 所以这:

var myobj = new MyObj();

myobj.a_custom_prop = 'something';

Would call a function being able to retrieve 'a_custom_prop' and 'something' 将调用一个能够检索“ a_custom_prop”和“某物”的函数

To be clear, I would like a function similar to: 需要明确的是,我想要一个类似于以下的函数:

MyObj.property.define = function (prop, value) { };

to be called like this: 被这样称呼:

myobj.prop = value;

instead of: 代替:

myobj.define('prop', value);

Knowing that the name of the property is not static relative to myobj , otherwise I would have used: 知道该属性的名称相对于myobj不是静态的,否则我会使用:

Object.defineProperty(MyObj.prototype, 'a_custom_prop', {
   set: function (value) { /*...*/ }
});

What you want is similar to method missing in Ruby, where you define a function that will handle calls to undefined methods. 您想要的类似于Ruby中method missing在Ruby中您定义了一个函数,该函数将处理对未定义方法的调用。

As you can read here: Does Javascript have something like Ruby's method_missing feature? 如您在这里所读: Javascript是否具有类似Ruby的method_missing功能? JavaScript doesn't have something similar yet, but there is a proposal for ES6: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy JavaScript还没有类似的东西,但是有ES6的建议: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

As Yoshi stated in a comment, it could be possible using Object.observe() from the ES7 draft. 正如Yoshi在评论中所述,可以使用ES7草案中的Object.observe()

However it's not exactly a "catch-all setter" because it will only be triggered after the property changed, not before. 但是,它并非完全是“包罗万象的设置器”,因为它只会在属性更改后才触发,而不是之前。 So, if for example you want to store the property somewhere else, you will have to delete it. 因此,例如,如果您要将属性存储在其他位置,则必须将其delete Since the observe callback is asynchronous, it will be ran after the current callstack, meaning the new value can be immediately used before being altered. 由于observe回调是异步的,它将在当前调用堆栈之后运行,这意味着新值可以在更改之前立即使用。

Also, Chrome only for now. 此外,Chrome仅适用于现在。

The following snippet does some manipulations on the object through native setting and using Object.observe . 以下代码段通过本机设置并使用Object.observe对对象进行了一些操作。 It logs in the following order: 它以以下顺序记录:

  1. I added this value: foobar 我添加了此值:foobar
  2. The callback retrieves: foobar 回调检索:foobar
  3. Value of foo.bar after deletion: undefined 删除后的foo.bar值:未定义

Here goes: 开始:

var foo = {};

Object.observe(foo, function(changes) {
  var lastChanges = changes[changes.length - 1],
      newValue = lastChanges.object[lastChanges.name];

  console.log('The callback retrieves: ' + newValue);
  delete lastChanges.object[lastChanges.name];
}, ['add']);

foo.bar = 'foobar'; //Log n°2
console.log('I added this value: ' + foo.bar); //Log n°1
setTimeout(function() {
  console.log('Value of foo.bar after deletion: ' + foo.bar); //Log n°3
}, 0); //Execute after the observe callback

Due to the fact that it's in the ES7 draft, the previous might be completely wrong depending on when you read this. 由于它在ES7草案中,因此根据您阅读本文的时间,以前的版本可能是完全错误的。

Couldn't you use something like this ? 你不能使用这样的东西吗?

function MyObj(){
 ...
 this.dynamicPropertyName = 'something';
 ...
}
MyObj.prototype.setThatProp = function(i){
 this[this.dynamicPropertyName] = i;
}
...
var myObj = new MyObj();
myObj.setThatProp(5);

EDIT: 编辑:

Or something like this : 或类似这样的东西:

MyObj.prototype.__defineSetter__('prop', function(val){ this[this.dynamicPropertyName] = val; });
...
var myObj = new MyObj();
myObj.prop = 5;

Example use : 使用示例:

控制台测试

否,目前无法执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM