在javascript中设置动态属性

时间:2015-04-30 10:18:05

标签: javascript

我想知道在Javascript中是否可以为动态属性设置一个setter?

所以这个:

var myobj = new MyObj();

myobj.a_custom_prop = 'something';

调用函数可以检索'a_custom_prop'和'something'

要清楚,我想要一个类似于以下的功能:

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

这样称呼:

myobj.prop = value;

而不是:

myobj.define('prop', value);

知道属性的名称相对于myobj不是静态的,否则我会使用:

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

4 个答案:

答案 0 :(得分:4)

你想要的东西类似于Ruby中的method missing,你可以在其中定义一个函数来处理对未定义方法的调用。

你可以在这里阅读:Does Javascript have something like Ruby's method_missing feature? JavaScript还没有类似的东西,但有一个针对ES6的提议: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

答案 1 :(得分:2)

正如Yoshi在评论中所述,可以使用ES7草案中的Object.observe()

然而,它并不完全是一个“全能定型者”,因为只有在属性发生变化后才会触发,而不是之前。因此,如果您想将该属性存储在其他位置,则必须delete它。由于observe回调是异步的,因此它将在当前的callstack之后运行,这意味着可以在更改之前立即使用新值。

此外,Chrome目前仅供使用。

以下代码段通过本机设置并使用Object.observe对对象进行一些操作。它按以下顺序登录:

  1. 我添加了这个值:foobar
  2. 回调检索:foobar
  3. 删除后foo.bar的值:undefined
  4. 这里是:

    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
    

    由于它是在ES7草案中,以前可能完全错误,具体取决于您何时阅读。

答案 2 :(得分:0)

你不能使用这样的东西吗?

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

编辑:

或类似的东西:

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

使用示例:

console test

答案 3 :(得分:-1)

不,目前无法实现。