C#里没有这种变态的方法。

虽然变态,但看起来不错的样子。

变量的解构赋值

  • 完全解构:本质上,这种写法属于“模式匹配”,;
  • 不完全解构:同时支持“不完全解构”
let [x, y] = [1, 2, 3];
x //
y // let [a, [b], d] = [1, [2, 3], 4];
a //
b //
d //
  • 数组:左边是数组,能遍历,但右边的不能,将报错。
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
  • 集合:事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"
  • 函数:fibs是一个 Generator 函数,原生具有 Iterator 接口。解构赋值会依次从这个接口获取值。
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
} let [first, second, third, fourth, fifth, sixth] = fibs();
sixth //
  • 默认值:当一个数组成员严格等于undefined,默认值才会生效
let [x = 1] = [undefined];
x // let [x = 1] = [null];  // null不严格等于undefined
x // null

若取到值,则不会触发默认值。

对象的解构赋值

对象的属性没有次序,变量必须与属性同名,才能取到正确的值。【字典匹配模式,不是通过位置】

简单匹配

  • key的匹配:
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb" let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
  • value的配置:
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa" let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

嵌套匹配

冒号代表的“模式”:如下,这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样【见2】。

let obj = {
p: [
'Hello',
{ y: 'World' }
]
}; let { p: [x, { y }] } = obj;
let { p, p: [x, { y }] } = obj; <----【2】
x // "Hello" 
y // "World"

强化理解:”模式“就是路径的效果。

const node = {
loc: {
start: {
line: 1,
column: 5
}
}
}; let { loc, loc: { start }, loc: { start: { line }} } = node;
loc // Object {start: Object}
start // Object {line: 1, column: 5}
line // 

模式的计算:不是圆括号,是方括号。

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first //
last //

危险区:路径若是”越界“了,报错。

// 报错
let {foo: {bar}} = {baz: 'baz'}; // foo这时等于undefined,再取子属性就会报错 let _tmp = {baz: 'baz'};
_tmp.foo.bar // 报错,这就好理解了,没有路径,越界了

危险区:只有不将大括号写在行首,避免 JavaScript 将其解释为代码块。

let x;
({x} = {x: 1});  // 可见圆括号的牛逼之处,such as ({} = 'abc'); 一个毫无意义的写法,但语法没问题!

  扩展 - 可以理解为对象

  • 字符串的解构赋值
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o" let {length : len} = 'hello';
len //
  • 数值和布尔值的解构赋值
let {toString: s} = 123;
s === Number.prototype.toString // true let {toString: s} = true;
s === Boolean.prototype.toString // true
  • undefined和null解构赋值
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

函数参数的解构赋值

支持多套参数:参数放在数组里。

[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]

默认值:

unction move({x = 0, y = 0} = {}) {
return [x, y];
} move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
} move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
[1, undefined, 3].map((x = 'yes') => x);
// [ 1, 'yes', 3 ]
    • 参数默认值可以与解构赋值的默认值,结合起来使用。
function fetch(url, { body = '', method = 'GET', headers = {} } = {}) {
console.log(method);
} fetch('http://example.com', {})
// "GET" fetch('http://example.com')  // 有了双重默认值就不会报错了
// 报错 

练习:

// 写法一
function m1({x = 0, y = 0} = {}) {      #设置了对象解构赋值的默认值
return [x, y];
} // 写法二
function m2({x, y} = { x: 0, y: 0 }) {
return [x, y];
}

几个实验:

// 函数没有参数的情况
m1() // [0, 0]
m2() // [0, 0] // x 和 y 都有值的情况
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8] // x 有值,y 无值的情况
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined] // x 和 y 都无值的情况
m1({}) // [0, 0];
m2({}) // [undefined, undefined] m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

[JS] ECMAScript 6 - Destructuring的更多相关文章

  1. [Node.js] ECMAScript 6中的生成器及koa小析

    原文地址:http://www.moye.me/2014/11/10/ecmascript-6-generator/ 引子 老听人说 koa大法好,这两天我也赶了把时髦:用 n 安上了node 0.1 ...

  2. [JS] ECMAScript 6 - Variable : compare with c#

    前言 范围包括:ECMAScript 新功能以及对象. 当前的主要目的就是,JS的学习 --> ECMAScript 6 入门 let 命令 js 因为let, i的范围限制在了循环中. var ...

  3. [JS] ECMAScript 6 - Class : compare with c#

    Ref: Class 的基本语法 Ref: Class 的基本继承 许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为.目前,有一个提案将这项功能,引入了 ECMAScript. ...

  4. [JS] ECMAScript 6 - Inheritance : compare with c#

    这一章,估计是js最操蛋的一部分内容. 现代方法: 简介 Object.getPrototypeOf() super 关键字 类的 prototype 属性和__proto__属性 原生构造函数的继承 ...

  5. [JS] ECMAScript 6 - String, Number, Function : compare with c#

    字符串的扩展 正则的扩展 数值的扩展 函数的扩展 字符串的扩展 js 字符的 Unicode 表示法 codePointAt() String.fromCodePoint() 字符串的遍历器接口 at ...

  6. [JS] ECMAScript 6 - Prototype : compare with c#

    开胃菜 prototype 对象 JavaScript 语言的继承则是通过“原型对象”(prototype). function Cat(name, color) { // <----构造函数 ...

  7. [JS] ECMAScript 6 - Async : compare with c#

    一段引言: Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大. 它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对 ...

  8. js (ECMAScript) 对数据处理的 方法、属性总结

    注意:原生类型的数据本身是没有属性.方法的.但是 有的原始类型(如 string),当他 调用属性或方法时,JS引擎会先对原始类型数据进行包装(即隐式的转换为相应的对象)  https://www.c ...

  9. JS ECMAScript 5中的every 和 some方法进行逻辑判断

    ECMA Script 5 中新增两个不错的关于数组元素的逻辑运算方法some, every Array.some(function(item){}); Array.every(function(it ...

随机推荐

  1. 如何调整eclipse中代码字体大小

    找到windows--->preferences---->General------>Appearance---->color   and fonts   ---->ba ...

  2. SimpleDateFormat 格式化参数说明

    字母 日期或时间元素 表示 示例 G Era 标志符 Text AD y 年 Year 1996; 96 M 年中的月份 Month July; Jul; 07 w 年中的周数 Number 27 W ...

  3. JS中JSON.parse和eval的异同

    1.相同点 JSON.parse和eval函数都可将一段json字符串转换为json对象,如: var json = '{"intro":[{"name":&q ...

  4. POI设置excle单元格样式

    Java利用POI生成Excel强制换行 使用POI创建一个简单的   myXls.xls   文件       常用的包为   org.apache.poi.hssf.usermodel.*;    ...

  5. kubeadm安装kubernetes V1.11.1 集群

    之前测试了离线环境下使用二进制方法安装配置Kubernetes集群的方法,安装的过程中听说 kubeadm 安装配置集群更加方便,因此试着折腾了一下.安装过程中,也有一些坑,相对来说操作上要比二进制方 ...

  6. .Net Core URL编码和解码

    一.URL说明 .Net Core中http 的常用操作封装在 HttpUtility 中 命名空间 using System.Web; // // 摘要: // Provides methods f ...

  7. 如何用 async 控制流程

    来自: http://larry850806.github.io/2016/05/31/async/ [Javascript] 如何用 async 控制流程 (一) 31 May 2016 async ...

  8. CentOS 6下 Oracle11gR2 设置开机自启动

    [1] 更改/etc/oratab # This file is used by ORACLE utilities. It is created by root.sh # and updated by ...

  9. 【C语言】字节对齐问题(以32位系统为例)

    1. 什么是对齐? 现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型 ...

  10. 9.4 翻译系列:EF 6以及 EF Core中的NotMapped特性(EF 6 Code-First系列)

    原文链接:http://www.entityframeworktutorial.net/code-first/notmapped-dataannotations-attribute-in-code-f ...