简体   繁体   English

Javascript:是否有 object 传播语法的“Symbol.iterator”类似物 - {...obj }?

[英]Javascript: is there "Symbol.iterator" analogue for the object spread syntax - { ...obj }?

There is a well known symbol: Symbol.iterator , that, when defined as a generator function property on an object, allows the object to be used in a [...object] syntax.有一个众所周知的符号: Symbol.iterator ,当定义为 object 上的生成器 function 属性时,允许 object 在[...object]语法中使用。 So, you can do, eg., this:所以,你可以这样做,例如:

const newArray = [ ...foo, ...object, ...bar ];

However, I couldn't find an analogue of that functionality, allowing this:但是,我找不到该功能的类似物,允许这样做:

const newObject = { ...foo, ...object, ...etc };

or Object.assign with non-own properties.Object.assign非自有财产。 Case in point: instances of ES6 classes with get prop() / set prop() accessors - they are defined on the .prototype property of the class constructor:恰当的例子:带有get prop() / set prop()访问器的 ES6 类的实例——它们在 class 构造函数的.prototype属性上定义:

const C = class {
  #num = 42;
  #str = 'aaa';
  
  get num() { return this.#num; }
  set num(val) { /* validate new value */ this.#num = val; return true; }

  get str() { return this.#num; }
  set str(val) { /* validate new value */ this.#num = val; return true; }
}

const obj = new C();

Now obj has built-in validation for obj.num =... and obj.str =... .现在obj内置了对obj.num =...obj.str =...的验证。 However, it cannot be used in {...foo, ...obj} , or in Object.assign(foo, obj) , because the accessors are on the prototype.但是,它不能在{...foo, ...obj}Object.assign(foo, obj)中使用,因为访问器在原型上。 Proxies can be spread, and property acces trapped for validation, but one of my goals is to make accessing obj.prop as close in performance as possible to accessing plain object prop .可以传播代理,并捕获属性访问以进行验证,但我的目标之一是使访问obj.prop的性能尽可能接近访问普通 object prop And look at this:看看这个:

const p = new Proxy({ num: 0 }, {});

suite.add('instance with class-accessors', () => obj.num++);
suite.add('proxy', () => p.num++);
suite.run();

instance with class-accessors x ***235***,971,841 ops/sec ±0.20% (86 runs sampled)
proxy x ***1***,014,238 ops/sec ±1.91% (84 runs sampled)

Two orders of magnitude slower!慢了两个数量级! So, is there a way to allow {...obj } / Object.assign for instances with prototype based getters?那么,有没有办法允许{...obj } / Object.assign用于具有基于原型的 getter 的实例?

I did experiment, just in case, with defining *[Symbol.iterator]() {...} in the class, yielding Object.entries -style pairs of [prop, val] , didn't work.我做了实验,以防万一,在 class 中定义*[Symbol.iterator]() {...} ,产生Object.entries风格的[prop, val]对,但没有用。 Didn't find anything useful on MDN's "Well known symbols".在 MDN 的“Well known symbols”上没有找到任何有用的东西。 Expected to find something like, eg., Symbol.entries , something that can control spread/assign and make instances with getters usage transparent.期望找到类似Symbol.entries的东西,它可以控制传播/分配并使具有 getters 使用的实例透明。

No, there is not.不,那里没有。 Object literal spread syntax just picks all enumerable own properties, that's it. Object 文字传播语法只是选择所有可枚举的自身属性,仅此而已。

The common workaround is to define a getter method to serialise an object that can be spread as you want, often also used for JSON conversion:常见的解决方法是定义一个 getter 方法来序列化一个 object 可以随意传播,通常也用于 JSON 转换:

 class C { #num = 42; #str = 'aaa'; get num() { return this.#num; } get str() { return this.#num; } // … toJSON() { return {num: this.#num, str: this.#str}; } } const object = new C(); const newObject = { x: 1, ...object.toJSON(), y: 2 }; console.log(newObject); console.log(JSON.stringify(object));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TypeError: Spread syntax requires...iterable[Symbol.iterator] 为 function - TypeError: Spread syntax requires ...iterable[Symbol.iterator] to be a function 传播一个可迭代的…obj[Symbol.iterator](…) - Spreading an iterable …obj[Symbol.iterator](…) 我可以通过原型在 Object 中使用 Symbol.iterator 吗?“JavaScript” - Do I can Symbol.iterator in Object by prototype?"JavaScript" 产生对象值的`Symbol.iterator` - `Symbol.iterator` that yields Object's values 调用[Symbol.iterator]()时未生成对象 - Object is not being produced on calling [Symbol.iterator]() 在 JavaScript ES6 中,每次调用 obj[Symbol.iterator] function 时,可迭代对象是否会吐出一个新的迭代器? - In JavaScript ES6, does an iterable spit out a new iterator each time the obj[Symbol.iterator] function is invoked? TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator)) JavaScript - TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator)) JavaScript Symbol.iterator:获取迭代器对象中所有对象的属性 - Symbol.iterator: get all the object's properties in iterator object JavaScript - 在 [Symbol.iterator]() 中选择返回 [Symbol.iterator]() 有什么用? - JavaScript - What's the use of giving the choice of returning [Symbol.iterator]() in a [Symbol.iterator]()? 为什么使用 JavaScript 中的 Symbol.iterator 创建迭代器? - Why Symbol.iterator in javascript is used to create iterator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM