javascript - 如何在 JS 中调用 thunk 来访问子对象属性?

标签 javascript oop prototype-programming

有一类对象,我需要在事后向其添加一些函数作为属性。因为这些函数必须引用实例变量才能配置作为属性附加的函数,所以我使用 thunk 来创建函数并转发第一个函数调用。一个简化的例子:

function Foo(val) {
  this.val = val;
}

// simulates a library call which returns a complex object with methods
// this library call requires access to some of the object information,
// simulated by passing in `type`
function buildWorkFunction(type) {
  var f = function() { return this.val; };
  if (type === 'string')
    f = function() { return this.val.length; };
  f.getType = function() { return type; };
  return f;
}

function addProperty(Base, prop) {
  var thunk = function() {
    // typeof is just a simple example of how buildWorkFunction could
    // change based on this.val
    this[prop] = buildWorkFunction(typeof this.val);
    return this[prop].apply(this, arguments);
  };
  thunk.getType = function() {
    return 'TODO'; // <-- this is the part I need help with
  };
  Base.prototype[prop] = thunk;
}

// simulates instances existing before the module load
var foo = new Foo('foo');

// runs after user requests a module load, runs from the module
setTimeout(function() {
  // adding a module specific property to the non-module model
  addProperty(Foo, 'getVal');

  console.log(foo.getVal());
  console.log(foo.getVal.getType());

  // simulates instances created after the module load
  var bar = new Foo(17);
  console.log(bar.getVal.getType()); // called before thunk - fails
  console.log(bar.getVal());
  console.log(bar.getVal.getType()); // called after thunk - works
}, 0);

我剩下的一个问题是,属性值本身具有应用程序代码有时会引用的属性,而无需调用属性本身,就像上面的 f.getType 一样。如何在不首先调用 foo.getVal() 的情况下正确捕获/代理/转发诸如 foo.getVal.getType() 之类的调用?附加属性的名称定义良好并且可以共享 - 但我不知道如何访问正确的 this 或其中的数据。

最佳答案

How can I properly catch/proxy calls such as foo.getVal.getType()? If foo.getVal() isn't called first, I can't see how to access the correct this or the data from them.

您可以使用与已经使用的相同的方法,但在属性 getter 级别而不是方法调用级别。这使得延迟创建任意实例属性成为可能:

function addProperty(Base, prop) {
  Object.defineProperty(Base.prototype, prop, {
    get: function thunk() {
      var propertyValue = buildWorkFunction(typeof this.val);
      //                                    ^^^^^^^^^^^^^^^ access the instance here
      // overwrite (shadow) the prototype getter:
      Object.defineProperty(this, prop, {
        value: propertyValue,
        writable: true,
        enumerable: true,
        configurable: true
      });
      return this[prop];
    },
    enumerable: true, // dunno
    configurable: true
  });
}

关于javascript - 如何在 JS 中调用 thunk 来访问子对象属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41005049/

相关文章:

javascript - 带有 Angular 和 ngx-gallery 的动态图像

c# - 数据传输对象和报告

java - 如何在两个父类上重用子类?

oop - DAO 和业务逻辑

Javascript错误: this. form is undefined,我无法在成员方法中获取对象变量

javascript - 我无法在 javascript 中扩展 String 原型(prototype)

prototypal-inheritance - 这个 Animal = function Animal 是做什么的?

javascript - 使用 css 单位计算表达式

javascript - 使用 CSS 和 JQuery 设置事件菜单项

javascript - 单元测试中的 Angular 1.x 服务注入(inject)