技术控

    今日:43| 主题:49507
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] ES proposal: Rest/Spread Properties

[复制链接]
攒度 发表于 2016-10-2 15:15:36
125 5

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
The ECMAScript proposal “    Rest/Spread Properties” by Sebastian Markbåge is currently at stage 3. It enables:  
  
       
  •       The rest operator (        ...) in object destructuring. At the moment, this operator only works for Array destructuring and in parameter definitions.      
       
  •       The spread operator (        ...) in object literals. At the moment, this operator only works in Array literals and in function and method calls.      
      
  The rest operator (    ...) in object destructuring  

  Inside object destructuring patterns, the rest operator (    ...) copies all enumerable own properties of the destructuring source into its operand, except those that were already mentioned in the object literal.  
  1. const obj = {foo: 1, bar: 2, baz: 3};
  2.     const {foo, ...rest} = obj;
  3.         // Same as:
  4.         // const foo = 1;
  5.         // const rest = {bar: 2, baz: 3};
复制代码
If you are using object destructuring to handle named parameters, the rest operator enables you to collect all remaining parameters:
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }
复制代码
Syntactic restrictions

  Per top level of each object literal, you can use the rest operator at most once and it must appear at the end:
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError
复制代码
You can, however, use the rest operator several times if you nest it:
  1. const obj = {
  2.         foo: {
  3.             a: 1,
  4.             b: 2,
  5.             c: 3,
  6.         },
  7.         bar: 4,
  8.         baz: 5,
  9.     };
  10.     const {foo: {a, ...rest1}, ...rest2} = obj;
  11.     // Same as:
  12.     // const a = 1;
  13.     // const rest1 = {b: 2, c: 3};
  14.     // const rest2 = {bar: 4, baz: 5};
复制代码
The spread operator (    ...) in object literals  

  Inside object literals, the spread operator (    ...) inserts all enumerable own properties of its operand into the object created via the literal:  
  1. > const obj = {foo: 1, bar: 2, baz: 3};
  2.     > {...obj, qux: 4}
  3.     { foo: 1, bar: 2, baz: 3, qux: 4 }
复制代码
Note that order matters even if property keys don’t clash, because objects record insertion order:
  1. > {qux: 4, ...obj}
  2.     { qux: 4, foo: 1, bar: 2, baz: 3 }
复制代码
If keys clash, order determines which entry “wins”:
  1. > const obj = {foo: 1, bar: 2, baz: 3};
  2.     > {...obj, foo: true}
  3.     { foo: true, bar: 2, baz: 3 }
  4.     > {foo: true, ...obj}
  5.     { foo: 1, bar: 2, baz: 3 }
复制代码
Common use cases for the object spread operator

  In this section, we’ll look at things that you can use the spread operator for. I’ll also show how to do these things via          Object.assign()    , which is very similar to the spread operator (we’ll compare them in more detail later).  
  Cloning objects

  Cloning the enumerable own properties of an object:
  1. const obj = ···;
  2.     const clone1 = {...obj};
  3.     const clone2 = Object.assign({}, obj);
复制代码
The prototypes of the clones are always    Object.prototype, which is the default for objects created via object literals:  
  1. > Object.getPrototypeOf(clone1) === Object.prototype
  2.     true
  3.     > Object.getPrototypeOf(clone2) === Object.prototype
  4.     true
  5.     > Object.getPrototypeOf({}) === Object.prototype
  6.     true
复制代码
Cloning an object, including its prototype:
  1. const obj = ···;
  2.     const clone1 = {__proto__: Object.getPrototypeOf(obj), ...obj};
  3.     const clone2 = Object.assign(
  4.         Object.create(Object.getPrototypeOf(obj)), obj);
复制代码
Note that    __proto__inside object literals is only a mandatory feature in web browsers, not in JavaScript engines in general.  
  True clones of objects

  If you want to faithfully copy all own properties and their attributes (    writable,    enumerable, ...), including getters and setters then    Object.assign()and the spread operator don’t work. You need to use    property descriptors:  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }0
复制代码
If you additionally want to preserve the prototype of    obj, you can use          Object.create()    :  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }1
复制代码
           Object.getOwnPropertyDescriptors()    is explained in “Exploring ES2016 and ES2017”.  
  Pitfall: cloning is always shallow

  Keep in mind that with all the ways of cloning that we have looked at, you only get shallow copies: If one of the original property values is an object, the clone will refer to the same object, it will not be (recursively, deeply) cloned itself:
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }2
复制代码
Various other use cases

  Merging two objects    obj1and    obj2:  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }3
复制代码
Filling in defaults for user data:
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }4
复制代码
Non-destructively updating property    foo:  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }5
复制代码
Inlining the default values for    fooand    bar:  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }6
复制代码
Spreading objects versus    Object.assign()  

  The spread operator and          Object.assign()    are very similar. The main difference is that spreading defines new properties, while    Object.assign()sets them. What exactly that means is explained later.  
  Both spread and    Object.assign()read values via a “get” operation  

  Both operations use normal “get” operations to read property values from the source, before writing them to the target. As a result, getters are turned into normal data properties during this process.
  Let’s look at an example:
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }7
复制代码
     originalhas the getter    foo(its          property descriptor    has the properties    getand    set):  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }8
复制代码
But it its clones    clone1and    clone2,    foois a normal data property (its property descriptor has the properties    valueand    writable):  
  1. function func({param1, param2, ...rest}) { // rest operator
  2.         console.log('All parameters: ',
  3.             {param1, param2, ...rest}); // spread operator
  4.         return param1 + param2;
  5.     }9
复制代码
Spread defines properties,    Object.assign()sets them  

  The spread operator defines new properties in the target,    Object.assign()uses a normal “set” operation to create them. That has two consequences.  
  Targets with setters

  First,    Object.assign()triggers setters, spread doesn’t:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError0
复制代码
The previous piece of code installs a setter    foothat is inherited by all normal objects.  
  If we clone    objvia    Object.assign(), the inherited setter is triggered:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError1
复制代码
With spread, it isn’t:
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError2
复制代码
     Object.assign()also triggers own setters during copying, it does not overwrite them.  
  Targets with read-only properties

  Second, you can stop    Object.assign()from creating own properties via inherited read-only properties, but not the spread operator:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError3
复制代码
The previous piece of code installs the read-only property    barthat is inherited by all normal objects.  
  As a consequence, you can’t use assignment to create the own property    bar, anymore (you only get an exception in strict mode; in sloppy mode, setting fails silently):  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError4
复制代码
In the following code, we successfully create the property    barvia an object literal. This works, because object literals don’t set properties, they    definethem:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError5
复制代码
However,    Object.assign()uses assignment for creating properties, which is why we can’t clone    obj:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError6
复制代码
Cloning via the spread operator works:
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError7
复制代码
Both spread and    Object.assign()only consider own enumerable properties  

  Both operations ignore all inherited properties and all enumerable own properties.
  The following object    objinherits one (enumerable!) property from    protoand has two own properties:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError8
复制代码
If you clone    obj, the result only has the property    ownEnumerable. The properties    inheritedEnumerableand    ownNonEnumerableare not copied:  
  1. const {...rest, foo} = obj; // SyntaxError
  2.     const {foo, ...rest1, ...rest2} = obj; // SyntaxError9
复制代码
友荐云推荐




上一篇:Markcook2.0,使用 Vue2.0 和 Vuex2.0 进行完全重构升级
下一篇:The Accidental DBA
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

liaoshiyong 发表于 2016-10-2 21:34:14
支持你哈..
回复 支持 反对

使用道具 举报

海冬 发表于 2016-10-6 02:36:32
当爱情不在的时候,请对他说声祝福,毕竟,曾经爱过。
回复 支持 反对

使用道具 举报

凌晨丶 发表于 2016-10-11 18:57:38
涨姿势
回复 支持 反对

使用道具 举报

wweerty 发表于 2016-10-20 13:43:09
抄水表,抄水表,楼主赶紧的开门!
回复 支持 反对

使用道具 举报

zyxin 发表于 2016-11-17 22:17:14
看这种帖子就要有种“雾里看花”的意境。
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表