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. nginx编译安装on mac

    一.编译安装模块 如果是原有包中就有的模块,编译时, ./configure --with-xxx 就可以, 如果是第三方模块,可使用 --add-module, 如果有多个模块的话,只需要多次使用- ...

  2. android: shell 命令

    adb是Android重要工具之一,以提供强大的特性,例如复制文件到设备或从设备复制文件.可以使用Android Shell命令行参数连接到手机本身,并发送基本的 shell 命令. 进入命令行,使用 ...

  3. Scala:Object-Oriented Meets Functional

    Have the best of both worlds. Construct elegant class hierarchies for maximum code reuse and extensi ...

  4. 移动端web禁止长按选择文字以及弹出菜单

    /*如果是禁用长按选择文字功能,用css*/ * { -webkit-touch-callout:none; -webkit-user-select:none; -khtml-user-select: ...

  5. 使用Linux(CentOS)搭建SVN服务器全攻略

    虽然在windows上搭建SVN很简单,但是效能却不高,这当然是和linux相比了.然而在linux上搭建SVN却非常繁琐,所以今天这篇文章就来一步一步教您如何在Centos上搭建SVN 安装 #yu ...

  6. 奇怪吸引子---NoseHoover

    奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...

  7. C#中流的读写器BinaryReader、BinaryWriter,StreamReader、StreamWriter详解【转】

    https://blog.csdn.net/ymnl_gsh/article/details/80723050 C#的FileStream类提供了最原始的字节级上的文件读写功能,但我们习惯于对字符串操 ...

  8. Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...

  9. 【jQuery Demo】图片瀑布流实现

    瀑布流就是像瀑布一样的网站——丰富的网站内容,特别是绚美的图片会让你流连忘返.你在浏览网站的时候只需要轻轻滑动一下鼠标滚轮,一切的美妙的图片精彩便可呈现在你面前.瀑布流网站是新兴的一种网站模式——她的 ...

  10. UVA 12293 - Box Game(博弈)

    UVA 12293 - Box Game 题目链接 题意:两个盒子,一開始一个盒子有n个球.一个仅仅有1个球,每次把球少的盒子中球消掉,把多的拿一些球给这个盒子.最后不能操作的输(球不能少于1个),A ...