解析JavaScript的ES6版本中的解构赋值(2)

结果也许会让你感到意外,但深究一下,其实原因很简单。在进行对象解构赋值时,被解构的对象将被强制转换为 Object,除 null 和 undefined 外,其它类型都可以被强制转换为对象。进行数组的结构赋值时,要求被解构的对象有一个遍历器。
默认值

可以为不存在的属性指定一个默认值:

var [missing = true] = []; console.log(missing); // true var { message: msg = "Something went wrong" } = {}; console.log(msg); // "Something went wrong" var { x = 3 } = {}; console.log(x); // 3 var [missing = true] = []; console.log(missing); // true var { message: msg = "Something went wrong" } = {}; console.log(msg); // "Something went wrong" var { x = 3 } = {}; console.log(x); // 3

实际应用
函数参数

作为开发人员,我们经常把一个包含多个属性的对象作为函数的参数,来实现更灵活的 API,而不是让 API 的使用者记住一些特定顺序的参数。我们可以使用对象的解构赋值,来避免每次使用参数时的属性访问:

function removeBreakpoint({ url, line, column }) { // ... } function removeBreakpoint({ url, line, column }) { // ... }

配置对象

完善上面的例子,我们可以为要被解构的对象属性提供默认值,这在对那些作为配置参数的对象非常实用,因为许多配置项都有一个合理的默认值。例如,jQuery 的 ajax 方法的第二个参数为一个配置对象,我们可以这样实现:

jQuery.ajax = function (url, { async = true, beforeSend = noop, cache = true, complete = noop, crossDomain = false, global = true, // ... more config }) { // ... do stuff }; jQuery.ajax = function (url, { async = true, beforeSend = noop, cache = true, complete = noop, crossDomain = false, global = true, // ... more config }) { // ... do stuff };

这避免了类似这样的重复代码:var foo = config.foo || theDefaultFoo;。
与迭代器一起使用

当遍历 Map 对象时,我们可以使用解构赋值来遍历 [key, value]:

var map = new Map(); map.set(window, "the global"); map.set(document, "the document"); for (var [key, value] of map) { console.log(key + " is " + value); } // "[object Window] is the global" // "[object HTMLDocument] is the document" var map = new Map(); map.set(window, "the global"); map.set(document, "the document"); for (var [key, value] of map) { console.log(key + " is " + value); } // "[object Window] is the global" // "[object HTMLDocument] is the document"

只遍历键:

for (var [key] of map) { // ... } for (var [key] of map) { // ... } 只遍历值: for (var [,value] of map) { // ... } for (var [,value] of map) { // ... }

返回多个值

返回一个数组,通过解构赋值提取到返回值:

function returnMultipleValues() { return [1, 2]; } var [foo, bar] = returnMultipleValues(); function returnMultipleValues() { return [1, 2]; } var [foo, bar] = returnMultipleValues();

或者,返回一个键值对的对象:

function returnMultipleValues() { return { foo: 1, bar: 2 }; } var { foo, bar } = returnMultipleValues(); function returnMultipleValues() { return { foo: 1, bar: 2 }; } var { foo, bar } = returnMultipleValues();

这两者都比使用中间变量好:

function returnMultipleValues() { return { foo: 1, bar: 2 }; } var temp = returnMultipleValues(); var foo = temp.foo; var bar = temp.bar; function returnMultipleValues() { return { foo: 1, bar: 2 }; } var temp = returnMultipleValues(); var foo = temp.foo; var bar = temp.bar;

采用延续式:

function returnMultipleValues(k) { k(1, 2); } returnMultipleValues((foo, bar) => ...); function returnMultipleValues(k) { k(1, 2); } returnMultipleValues((foo, bar) => ...);

导入 CommonJS 模块的指定部分

还没使用过 ES6 的模块吧,那至少使用过 CommonJS 吧。当导入一个 CommonJS 模块 X 时,模块提供的方法也许多余你实际使用的。使用解构赋值,你可以明确指定你需要使用模块的哪些部分:

const { SourceMapConsumer, SourceNode } = require("source-map"); const { SourceMapConsumer, SourceNode } = require("source-map");

如果你使用 ES6 的模块机制,你可以看到 import 声明时有一个类似的语法。
结论

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgdwff.html