你必须收藏的 ES6 语法密糖 - Spread Operator 技巧
栏目: JavaScript · 发布时间: 5年前
内容简介:Spread Operator 是我最喜欢的语法糖,没有之一,在应用场景上也是最为广泛,下面说下使用场景和技巧。这是对应的babel 插件,当然直接使用 typescript 或者直接使用 omi-cli 已经内置了这个特性,可以直接使用。
Spread Operator 是我最喜欢的语法糖,没有之一,在应用场景上也是最为广泛,下面说下使用场景和技巧。
这是对应的babel 插件,当然直接使用 typescript 或者直接使用 omi-cli 已经内置了这个特性,可以直接使用。
不使用 Apply
apply 和 call 可以执行函数,改变 this 执行,比如:
function add(a, b){ return a + b } 复制代码
假设有个场景参数是以数组的形式传递过来,传统的做法是:
const args = [11, 12] add.apply(null, args) 复制代码
或者
const args = [11, 12] add.call(null, args[0], args[1]) 复制代码
使用 Spread Operator 之后:
const args = [11, 12] add(...args) 复制代码
babel 编译后的结果:
function add(a, b) { return a + b; } var args = [11, 12]; add.apply(undefined, args); 复制代码
常见的场景还有:
const arr = [1, 2, 3, 4, 5] Math.min(...arr) //求最小值 Math.max(...arr) //求最大值 复制代码
babel 编译后的结果:
var arr = [1, 2, 3, 4, 5]; Math.min.apply(Math, arr); //求最小值 Math.max.apply(Math, arr); //求最大值 复制代码
因为 Math.min 和 Math.max 参数个数是不限制的,所以这种场景非常适合使用 Spread Operator 。
合并数组
先看下 array push 的语法:
array.push(item1, item2, ...., item3) 复制代码
可以看到 push 接收的参数也是不定,所以可以利用其实现合并数组功能:
arr1.push(...arr2) 复制代码
或者合并到前方:
arr1.unshift(...arr2) 复制代码
也可以直接声明式合并:
const arr1 = [2, 3] const arr2 = [1, ...arr1, 4] //arr2 相当于 [1, 2, 3, 4] 复制代码
在比如:
const a = [1, 2] a.push(...[3, 4, 5]) //[1,2,3,4,5] 复制代码
babel 编译后:
var a = [1, 2]; a.push.apply(a, [3, 4, 5]); 复制代码
把 arguments 或 NodeList 转成数组
[...document.querySelectorAll('div')] 复制代码
bebel 编译后:
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } [].concat(_toConsumableArray(document.querySelectorAll('div'))); 复制代码
直接把 arguments 转成数组:
var myFn = function(...args) { console.log(args.forEach) //ƒ forEach() { [native code] } console.log(arguments.forEach) //undefined } myFn() 复制代码
babel 编译后:
var myFn = function myFn() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } console.log(args.forEach); //ƒ forEach() { [native code] } console.log(arguments.forEach); //undefined }; myFn(); 复制代码
快速赋值
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; console.log(x); // 1 console.log(y); // 2 console.log(z); // { a: 3, b: 4 } 复制代码
babel 编译后:
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } var _x$y$a$b = { x: 1, y: 2, a: 3, b: 4 }, x = _x$y$a$b.x, y = _x$y$a$b.y, z = _objectWithoutProperties(_x$y$a$b, ["x", "y"]); 复制代码
Spread 实战
return [list, { set, push: (entry) => set([...list, entry]), filter: (fn) => set(list.filter(fn)), sort: (fn?) => set([...list].sort(fn)), }]; }; 复制代码
<button onClick={() => setItems([...items, { text: 'new item' }])}> add </button> <button onClick={() => setItems([])}>empty</button> 复制代码
当然我自身不喜欢这种方式定义组件,所以在 omio 中没有加入类似的功能。
Omi extractclass
import { classNames, extractClass } from 'omi' define('my-element', class extends WeElement { render(props) { //extractClass will take out this class/className from props and merge the other classNames to obj const cls = extractClass(props, 'o-my-class', { 'other-class': true, 'other-class-b': this.xxx === 1 }) return ( <div {...cls} {...props}> Test </div> ) } }) 复制代码
extractClass
简直是写 UI 组件的神器,该方法会提取出 props 的 class 或者 className,并且进行类似 classNames 库的合并。最后通过扩展运算符增加到 JSX 上。
Omiu button 实战
import { define, WeElement, extractClass } from 'omi' import css from './_index.css' define('o-button', class extends WeElement { static defaultProps = { disabled: false, type: 'primary', size: 'normal' } css() { return css } render(props) { //提取 class,并从 props 中去掉 let cls = extractClass(props) || {} const { component, type, size, plain, children, ...others } = this.props const Component = component ? component : this.props.href || type === 'vcode' ? 'a' : 'button' cls = type === 'vcode' ? extractClass(cls, 'weui-vcode-btn') : extractClass(cls, { 'weui-btn': true, 'weui-btn_mini': size === 'small', 'weui-btn_primary': type === 'primary' && !plain, 'weui-btn_default': type === 'default' && !plain, 'weui-btn_warn': type === 'warn', 'weui-btn_plain-primary': type === 'primary' && plain, 'weui-btn_plain-default': type === 'default' && plain, 'weui-btn_disabled': this.props.disabled && !plain, 'weui-btn_plain-disabled': this.props.disabled && plain }) return ( <Component {...others} {...cls}> {children} </Component> ) } }) 复制代码
extractClass 源码
export function extractClass() { //提取第一个参数 props 和剩余的 args const [props, ...args] = Array.prototype.slice.call(arguments, 0) if (props.class) { args.unshift(props.class) delete props.class } else if (props.className) { args.unshift(props.className) delete props.className } if (args.length > 0) { return { class: classNames.apply(null, args) } } } 复制代码
可以看到 extractClass 本身也用到了 Spread Operator,真实无处不在。
以上所述就是小编给大家介绍的《你必须收藏的 ES6 语法密糖 - Spread Operator 技巧》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Swift语法快速入门(一)之 Swift基础语法
- 在ES6中使用扩展语法有什么好处?它与rest语法有什么不同?
- Python 基础语法
- go语法
- JPQL 语言语法
- reStructuredText简明语法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Effective Modern C++ 简体中文版
Scott Meyers / 高博 / 中国电力出版社 / 2018-4-23 / 99
想要彻底理解C++11和C++14,不可止步于熟悉它们引入的语言特性(例如,auto型别推导、移动语义、lambda表达式以及并发支持)。挑战在于高效地运用这些特性——从而使你的软件具备正确性、高效率、可维护性和可移植性。这正是这本实用的图书意欲达成的定位。它描述的正是使用C++11和C++14——现代C++来撰写真正卓越的软件之道。 涵盖以下主题: 大括号初始化、noexcept规格......一起来看看 《Effective Modern C++ 简体中文版》 这本书的介绍吧!