Cha*_*lie 5 javascript destructuring ecmascript-6
函数参数解构是ES6中的一个惊人特性.假设我们希望一个functionnamed f接受一个Object有a密钥的
function f({ a }) {
return a;
}
Run Code Online (Sandbox Code Playgroud)
对于未提供参数的情况,我们有默认值以避免 Type Error
function f({ a } = {}) {
return a;
}
Run Code Online (Sandbox Code Playgroud)
这将有助于以下情况
const a = f(); // undefined
Run Code Online (Sandbox Code Playgroud)
虽然,它会失败
const a = f(null); // TypeError: Cannot match against 'undefined' or 'null'.
Run Code Online (Sandbox Code Playgroud)
您可以在这里看到Babel如何将功能转换为ES5 .
通过参数验证和预处理可以避免这种情况.在Python我可以使用装饰器,但在JS中我们没有它们标准化,所以使用它们不是一个好主意.但是,假设我们有一个装饰器checkInputObject,它使用给定的项目列表(或嵌套解构的情况下的树)进行必要的检查并提供默认值.我们可以在没有@表示法的情况下以下列方式使用它
const f = checkInputObject(['a'])(({ a }) => a);
Run Code Online (Sandbox Code Playgroud)
它可能看起来像带@符号
@checkInputObject(['a'])
function f({ a }) {
return a;
}
Run Code Online (Sandbox Code Playgroud)
此外,我可以在函数本身中进行所有需要的操作,然后才使用解构,但在这种情况下,我失去了函数参数解构的所有优点(我根本不会使用它)
function f(param) {
if (!param) {
return;
}
const { a } = param;
return a;
}
Run Code Online (Sandbox Code Playgroud)
我甚checkInputObject至可以实现一些常见的功能,以便在函数内部使用它
const fChecker = checkInputObject(['a']);
function f(param) {
const { a } = fChecker(param);
return a;
}
Run Code Online (Sandbox Code Playgroud)
但是,使用附加代码对我来说并不优雅.我想没有现有的实体被分解为undefined.假设我们有
function f({a: [, c]) {
return c;
}
Run Code Online (Sandbox Code Playgroud)
得到undefined的情况会很好f().
你知道任何优雅和方便的方法使[嵌套]解构抵抗不存在的嵌套键吗?
我关注的是:看起来这个功能对于在公共方法中使用是不安全的,我需要在使用之前自己进行验证.这就是为什么它在私人方法中使用之前似乎毫无用处.
在 ES6 中处理此问题的正确方法是尊重语言和形状 API 处理参数的方式,以更好地适应它,而不是相反。
解构参数背后的语义fn(undefined)是参数将被替换为默认值,在 的情况下意味着fn(null)空参数不会被默认值替换。
如果数据来自外部并且应该进行条件/预处理/验证,则应该显式处理,而不是通过解构:
function fn({ foo, bar}) { ... }
fn(processData(data));
Run Code Online (Sandbox Code Playgroud)
或者
function fn(data) {
const { foo, bar } = processData(data);
...
}
fn(data);
Run Code Online (Sandbox Code Playgroud)
processData应该调用的地方完全由开发人员决定。
@由于提议的 ECMAScript 装饰器只是具有特定签名的辅助函数,因此根据项目的不同,相同的辅助函数可以用于语法和常用函数调用。
function processDataDecorator(target, key) {
const origFn = target[key];
return target[key] = (...args) => origFn.apply(target, processData(...args));
}
class Foo {
constructor() {
this.method = processDataDecorator(this, 'method');
}
method(data) {...}
}
class Bar {
@processDataDecorator
method(data) {...}
}
Run Code Online (Sandbox Code Playgroud)
自 ES5 以来,该语言提供的默认属性值的方式是Object.assign. dataisundefined或其他原语并不重要null,结果将始终是一个对象:
function processData(data) {
return Object.assign({ foo: ..., bar: ...}, data);
}
Run Code Online (Sandbox Code Playgroud)