Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
访问JavaScript对象的默认getter/setter_Javascript_Setter_Getter_Defineproperty - Fatal编程技术网

访问JavaScript对象的默认getter/setter

访问JavaScript对象的默认getter/setter,javascript,setter,getter,defineproperty,Javascript,Setter,Getter,Defineproperty,可以使用Object.defineProperty为特定属性重写JavaScript getter和setter。是否有某种方法可以访问默认的getter/setter(即,如果getter/setter未被覆盖,则使用的函数)?在我的自定义setter中,我希望在某些情况下进行特殊处理,但在其他情况下使用默认处理。我试过: Object.defineProperty(obj, 'foo', 'set': function(val) { if (useCustom) {

可以使用
Object.defineProperty
为特定属性重写JavaScript getter和setter。是否有某种方法可以访问默认的getter/setter(即,如果getter/setter未被覆盖,则使用的函数)?在我的自定义setter中,我希望在某些情况下进行特殊处理,但在其他情况下使用默认处理。我试过:

Object.defineProperty(obj, 'foo',
  'set': function(val) {
    if (useCustom) {
      doCustomProcessing(obj, 'foo', val);
    }
    else {
      obj['foo'] = val;
    }
  }
);

不幸的是,这会导致堆栈溢出,因为
obj['foo']=val导致调用自定义setter。因此,我想找到一种方法,使用默认setter设置
obj
foo
属性。这可能吗?

据我所知,一个属性要么有一个值(数据属性),要么有getter/setter(访问器属性):它不能两者都有。使用闭包下的局部变量或其他属性作为已定义getter/setter的属性的基础存储

比如说,

(function() {
    var value;
    Object.defineProperty(obj, 'foo', {
      set: function(val) {
        if (useCustom) {
          value = doCustomProcessing(obj, 'foo', val);
        } else {
          value = val;
        }
      },
      get: function() { return value; }
    });
})();

我知道的唯一方法是使变量非私有,但有两个示例,第二个更简洁:

(function testInheritance(global, doc) {
  "use strict";
  var MyFunc = Object.create({}, {
      _foo: {
        value: "Some Default Value",
        writable: true,
        enumerable: true
      },
      foo: {
        get: function() {
          return this._foo;
        },
        set: function(value) {
          this._foo = value;
        }
      }
    }),
    testFunc = Object.create(MyFunc);
  console.log(testFunc.foo); // "Some default value"
  testFunc.foo = "boo";
  console.log(testFunc.foo); // "boo";
 testFunc._foo = "Not a private variable anymore";
 console.log(testFunc.foo); // "Not a private variable anymore"
}(window, document));

(function testInheritanceTwo(global, doc) {
  "use strict";
  var MyFunc = Object.create({}, {
      foo: {
        get: function() {
          if (!this._foo) {
             return "Some default value set by the getter.";
          }
          return this._foo;
        },
        set: function(value) {
          this._foo = value;
        }
      }
    }),
    testFunc = Object.create(MyFunc);
  console.log(testFunc.foo); // "Some default value set by the getter."
  testFunc.foo = "Whomp";
  console.log(testFunc.foo); // "Whomp";
 testFunc._foo = "Not a private variable anymore, unfortunately.";
 console.log(testFunc.foo); // "Not a private variable anymore"
}(window, document));
据我所知:

  • 不能使用与set:function(value)中使用的名称相同的名称引用该值,否则最终会出现一个无限循环,在该循环中,设置该值会调用set值,然后它会再次调用自身,以此类推。因此,你的问题

  • 如果试图将变量_foo设置为private,则setter无法工作。使用这种语法,似乎可以隐藏变量,但不能真正将其私有化

  • 在ES6中,您可以使用:


    您可以执行以下操作:

    const counter=新类{
    计数=1;
    toString(){
    返回这个.count++;
    }
    }()
    
    log(`${counter}`')
    @OP,要查看有关数据属性与访问器属性的更多信息,请参阅。
    var myObject = {};
    
    var myProxyObject = new Proxy(myObject, {
      set: function(ob, prop, value) {
        if (prop === 'counter' && value === 10) {
          // Some specialised behaviour
          ob.counter = 0;
        }
        else {
          // Default setter behaviour.
          ob[prop] = value;
        }
        // Return true otherwise you will get a TypeError in strict mode.
        return true;
      }
    });
    
    >>> myProxyObject.counter = 5;
    >>> console.log(myProxyObject.counter);
    5
    
    >>> myProxyObject.counter = 10;
    >>> console.log(myProxyObject.counter);
    0