Javascript setter和getter over prototype initialization function

时间:2018-01-13 04:36:23

标签: javascript javascript-objects

初始化javascript对象时,我想从函数执行中获取属性值。

到那时,我的对象看起来像这样:

request.resource.data.status == "new" || "viewed";

很明显,每次调用request.resource.data.status == "new" || request.resource.data.status == "viewed"; 时,var objectName = function(){} objectName.prototype.initialize = function() { this.attribute = functionOne(); functionOne() { return httpRequest(); } } 都会被执行,并且因为它是异步函数,结果是instance.attribute。我知道我需要getter和setter方法来实现这一点,但是这样做的正确方法是保持这个原型结构。

我尝试了以下

functionOne

但是当我拨打undefined时,我收到了此错误:

objectName.prototype.initialize = function() {
  this.attribute = undefined;
  Object.defineProperty(this, "attribute", {
    get: function() { return this.attribute },
    set: functionOne()
  });
}

1 个答案:

答案 0 :(得分:0)

const objectName = function(){}

const objectName.prototype.initialize = function() {
  this.attribute = undefined;
  Object.defineProperty(this, "attribute", {
    get: function() { return this.attribute },
    set: functionOne()
  });
}

const instance = new objectOne()

// This is infinitely recursive
instance.attribute 
// because instance.attribute invokes attribute getter, which returns instance.attribute
// which invokes attribute getter, which returns instance.attribute, which invokes ......
// which "eventually" (actually within a few microseconds) overflows the stack
var objectName = function(){}

objectName.prototype.initialize = function() {
  // Function called immediately when you initialize. Result is
  // essentially cached to this.attribute.
  this.attribute = functionOne();

  // returns whatever httpRequest returns
  function functionOne() {
    return httpRequest();
  }
}

由于httpRequest显然是异步的,因此基本上有两种类型的回报:

  1. 新的或维护良好的模块可能会提供promise API,在这种情况下,您可以在返回的承诺上调用.then
  2. instance.attribute.then(function(attr) {
      doSomethingWithAttribute(attr)
    })
    
    // or 
    
    (async function() {
      const attr = await instance.attribute
      doSomethingWithAttribute(attr)
    })()
    
    1. 较旧的模块可能会使用回调系统。所以你需要立即传递一个功能。
    2. var objectName = function(){}
      
      objectName.prototype.initialize = function() {
        // Notice I removed the parens here, this is no longer just about
        // immediate invocation. We need a callback to give to httpRequest.
        // so now attribute is basically an alias for functionOne. You could
        // instead accept a callback to attribute and pass it on to functionOne.
        this.attribute = functionOne;
      
        functionOne(callback) {
          return httpRequest(callback);
        }
      }
      
      // Just for reference, but not relevant to the question, this is a more concise
      // version of the function above assigned to objectName.prototype.initialize.
      const equivalentInitialize = {
        this.attribute = function(callback) {
          return httpRequest(callback);
        };
      }
      
      const instance = new objectOne()
      instance.attribute(doSomethingWithAttribute)
      

      为了使其更具可组合性,您可以将回调API包装在promise中。

      var objectName = function(){}
      
      objectName.prototype.initialize = function() {
        this.attribute = new Promise(resolve => {
          httpRequest(resolve)
        })
      }
      
      const instance = new objectName()
      instance.atttribute
        .then(doSomethingWithAttribute)
      

      更好的是,你可以忘记所有这些getter和setter废话,这在Javascript中甚至没有提供你认为它的安全性。

      // Making some wild guesses about api here, since I don't what you are using 
      // here to make a request
      
      httpRequest({ url, method, apiKey })
        .then(doSomethingWithResponse)