javascript - 是否可以在不调用 getter 的情况下将多个对象与 getter 合并

标签 javascript

所以我想扩展一些类(class)。除了这些类有 getter 之外,每当我想通过解构来合并/扩展它们的属性时,它都会调用 getter 函数(调用 getter 函数)。

有没有办法在不调用 getter 的情况下将对象与 getter 合并?

注意:

The actual problem I have involves cypress and chaining. I have deeply nested getters (in which I'd like extended classes to extend them) and it's causing unwanted side effects, like an extra chain which causes undesired behaviour.

如果运行下面的示例,您将看到多个 console.log 被调用(这意味着多个

class Test {
    get obj () {
        return {
            get test () {
                const _this = this;
                return {
                    get first () {
                        const out = _this.wrapper + 'first';
                        console.log( out );
                        return out;
                    }
                };
            },
            get wrapper () {
                const out = 'wrapper';
                console.log( out );
                return out;
            }
        };
    }
}

class Test1 extends Test {
    get obj () {
        const parent = super.obj;
        return {
            ...parent,
                get test() {
                console.log( parent );
                return {
                    ...parent.test,
                    get second () {
                        return super.wrapper + 'hello';
                    }
                };
            }
        }
    }
}

const t = new Test();
const t1 = new Test1();
console.log( t1.obj.test.second );

最佳答案

您可以使用Object.getOwnPropertyDescriptors来获取对对象描述符(包括getter)的引用,而无需调用它们。使用 Object.defineProperties 将其放入新对象中。

要添加其他 getter,请在克隆对象上使用 Object.defineProperty

const cloneObj = obj => Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));

class Test {
  get obj() {
    return {
      get name() {
        const _this = this
        return {
          get first() {
            const out = _this.wrapper + 'first'
            console.log('get first:', out)
            return out
          }
        }
      },
      get wrapper() {
        const out = 'wrapper'
        console.log('get wrapper:', out)
        return out
      }
    }
  }
}

class Test1 extends Test {
  get obj() {
    const parent = super.obj
    const parentClone = cloneObj(parent);
    Object.defineProperty(parentClone, 'name', { get() {
      console.log('child name getter:', parent)
      const parentNameClone = cloneObj(parent.name);
      Object.defineProperty(parentNameClone, 'second', { get() {
        console.log('child second getter:', parent)
        return super.wrapper + 'hello';
      }});
      return parentNameClone;
    }});
    return parentClone;
  }
}

const t1 = new Test1()
console.log('objects fully instantiated.');
console.log(t1.obj.name.second)

结果:

enter image description here

不要启用 Stack Snippet 控制台,这会令人困惑,因为它会在尝试显示对象时调用 getter 本身。

关于javascript - 是否可以在不调用 getter 的情况下将多个对象与 getter 合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67411624/

相关文章:

javascript - 如何在 Microsoft Edge 浏览器中调整弹出窗口的大小和移动弹出窗口?

javascript - 使用 javascript 将数据从一个页面传递到另一个页面的现代简单方法是什么?

javascript - D3 中的数组变换

javascript - 从 cookie javascript 捕获特定值

javascript - 使用 Node REPL 记录 __dirname 的值

javascript - JS matchMedia if 语句

javascript - JavaScript 中的 R 变量

javascript - 如何将 php 中接收到的数据分类为 html 中的 3 个不同的 div 标签?

javascript - 当多个div重叠时如何组织事件

javascript - ionic 滚动上的 Angular 变化样式