JavaScript使用装饰器来更改静态类字段的值吗?

huangapple go评论51阅读模式
英文:

Javascript use decorator to change static class field value?

问题

以下是翻译的内容:

"Is it possible for a JS field decorator to change its value?"

"JS字段装饰器是否可以更改其值?"

"A simplified use case would be something like this:"

"一个简化的用例可以如下所示:"

"Using the following experimental decorators:"

"使用以下实验性装饰器:"

"End goal is to make a decorator to inject tailwind style sheets into a lit elements static styles. Currently using a mixin for this but just doing this for fun and to learn what's possible with decorators."

"最终目标是创建一个装饰器,将Tailwind样式表注入到lit元素的static styles中。目前正在使用一个混入实现这个目标,但只是出于娱乐和学习装饰器的潜在用途。"

"Update to Barmars comments"

"针对Barmars的评论更新"

"When trying to return a value from the inner function, I end up getting an error:"

"当尝试从内部函数返回一个值时,我遇到了一个错误:"

"Uncaught TypeError: An element descriptor's .kind property must be either 'method' or 'field', but a decorator created an element descriptor with .kind 'undefined'"

"未捕获的TypeError:元素描述符的.kind属性必须是'method'或'field',但装饰器创建了一个带有.kind属性'undefined'的元素描述符"

"Looking at the documentation, the variables getting passed to each of these functions doesn't seem to match either."

"查看文档后,传递给这些函数的变量似乎也不匹配。"

"When running that example, the 2nd parameter to logged() is undefined. 'initialValue' also is an object, not the value:"

"运行示例时,传递给logged()的第二个参数是未定义的。'initialValue'也是一个对象,而不是值:"

英文:

Is it possible for a JS field decorator to change its value?

A simplified use case would be something like this:

const addItem = (newValue) => {
  return function (target) {
    target.value.push(newValue);
  };
};

class Test {
  @addItem(4)
  static values = [1,2,3];
}

const test = new Test();
console.log(test.constructor.values) // [1,2,3,4]

Using the following experimental decorators:

  '@babel/plugin-proposal-decorators',
  {
    version: '2018-09',
    decoratorsBeforeExport: true,
  },

End goal is to make a decorator to inject tailwind style sheets into a lit elements static styles. Currently using a mixin for this but just doing this for fun and to learn whats possible with decorators.

Update to Barmars comments

When trying to return a value from the inner function, I end up getting an error:

export const addItem = (value) => {
  return function (target) {
    return [value];
  };
};

Uncaught TypeError: An element descriptor's .kind property must be either "method" or "field", but a decorator created an element descriptor with .kind "undefined"

Looking at the documentation, the variables getting passed to each of these functions doesn't seem to match either.

function logged(value, { kind, name }) {
  if (kind === "field") {
    return function (initialValue) {
      console.log(`initializing ${name} with value ${initialValue}`);
      return initialValue;
    };
  }
}

When running that example, the 2nd parameter to logged() is undefined. "initialValue" also is an object, not the value:

Object { kind: "field", key: "styles", placement: "own", descriptor: {…}, initializer: value(), … }

答案1

得分: 1

尼科洛·里鲍多在 Babel 的讨论中帮助了我。正确的做法是使用初始化函数:

const addItem = (newValue) => {
  return function (target) {
    const { initializer } = target;
    target.initializer = function () {
      return [
        ...initializer.call(this),
        newValue,
      ];
    };
  };
};

class Test {
  @addItem(4)
  static values = [1,2,3];
}

const test = new Test();
console.log(test.constructor.values) // [1,2,3,4]
英文:

Nicolo Ribaudo was able to help me over on Babel's discussions. The correct way to do this is to use the initializer function:

const addItem = (newValue) => {
  return function (target) {
    const { initializer } = target;
    target.initializer = function () {
      return [
        ...initializer.call(this),
        newValue,
      ];
    };
  };
};

class Test {
  @addItem(4)
  static values = [1,2,3];
}

const test = new Test();
console.log(test.constructor.values) // [1,2,3,4]

huangapple
  • 本文由 发表于 2023年2月16日 06:51:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75466164.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定