[JS] ECMAScript 6 - Destructuring
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的更多相关文章
- [Node.js] ECMAScript 6中的生成器及koa小析
原文地址:http://www.moye.me/2014/11/10/ecmascript-6-generator/ 引子 老听人说 koa大法好,这两天我也赶了把时髦:用 n 安上了node 0.1 ...
- [JS] ECMAScript 6 - Variable : compare with c#
前言 范围包括:ECMAScript 新功能以及对象. 当前的主要目的就是,JS的学习 --> ECMAScript 6 入门 let 命令 js 因为let, i的范围限制在了循环中. var ...
- [JS] ECMAScript 6 - Class : compare with c#
Ref: Class 的基本语法 Ref: Class 的基本继承 许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为.目前,有一个提案将这项功能,引入了 ECMAScript. ...
- [JS] ECMAScript 6 - Inheritance : compare with c#
这一章,估计是js最操蛋的一部分内容. 现代方法: 简介 Object.getPrototypeOf() super 关键字 类的 prototype 属性和__proto__属性 原生构造函数的继承 ...
- [JS] ECMAScript 6 - String, Number, Function : compare with c#
字符串的扩展 正则的扩展 数值的扩展 函数的扩展 字符串的扩展 js 字符的 Unicode 表示法 codePointAt() String.fromCodePoint() 字符串的遍历器接口 at ...
- [JS] ECMAScript 6 - Prototype : compare with c#
开胃菜 prototype 对象 JavaScript 语言的继承则是通过“原型对象”(prototype). function Cat(name, color) { // <----构造函数 ...
- [JS] ECMAScript 6 - Async : compare with c#
一段引言: Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大. 它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对 ...
- js (ECMAScript) 对数据处理的 方法、属性总结
注意:原生类型的数据本身是没有属性.方法的.但是 有的原始类型(如 string),当他 调用属性或方法时,JS引擎会先对原始类型数据进行包装(即隐式的转换为相应的对象) https://www.c ...
- JS ECMAScript 5中的every 和 some方法进行逻辑判断
ECMA Script 5 中新增两个不错的关于数组元素的逻辑运算方法some, every Array.some(function(item){}); Array.every(function(it ...
随机推荐
- nginx编译安装on mac
一.编译安装模块 如果是原有包中就有的模块,编译时, ./configure --with-xxx 就可以, 如果是第三方模块,可使用 --add-module, 如果有多个模块的话,只需要多次使用- ...
- android: shell 命令
adb是Android重要工具之一,以提供强大的特性,例如复制文件到设备或从设备复制文件.可以使用Android Shell命令行参数连接到手机本身,并发送基本的 shell 命令. 进入命令行,使用 ...
- Scala:Object-Oriented Meets Functional
Have the best of both worlds. Construct elegant class hierarchies for maximum code reuse and extensi ...
- 移动端web禁止长按选择文字以及弹出菜单
/*如果是禁用长按选择文字功能,用css*/ * { -webkit-touch-callout:none; -webkit-user-select:none; -khtml-user-select: ...
- 使用Linux(CentOS)搭建SVN服务器全攻略
虽然在windows上搭建SVN很简单,但是效能却不高,这当然是和linux相比了.然而在linux上搭建SVN却非常繁琐,所以今天这篇文章就来一步一步教您如何在Centos上搭建SVN 安装 #yu ...
- 奇怪吸引子---NoseHoover
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- C#中流的读写器BinaryReader、BinaryWriter,StreamReader、StreamWriter详解【转】
https://blog.csdn.net/ymnl_gsh/article/details/80723050 C#的FileStream类提供了最原始的字节级上的文件读写功能,但我们习惯于对字符串操 ...
- Linux及Arm-Linux程序开发笔记(零基础入门篇)
Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...
- 【jQuery Demo】图片瀑布流实现
瀑布流就是像瀑布一样的网站——丰富的网站内容,特别是绚美的图片会让你流连忘返.你在浏览网站的时候只需要轻轻滑动一下鼠标滚轮,一切的美妙的图片精彩便可呈现在你面前.瀑布流网站是新兴的一种网站模式——她的 ...
- UVA 12293 - Box Game(博弈)
UVA 12293 - Box Game 题目链接 题意:两个盒子,一開始一个盒子有n个球.一个仅仅有1个球,每次把球少的盒子中球消掉,把多的拿一些球给这个盒子.最后不能操作的输(球不能少于1个),A ...