你必须收藏的 ES6 语法密糖 - Spread Operator 技巧

栏目: JavaScript · 发布时间: 6年前

内容简介: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 实战

react useomi use

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 技巧》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Machine Learning in Action

Machine Learning in Action

Peter Harrington / Manning Publications / 2012-4-19 / GBP 29.99

It's been said that data is the new "dirt"—the raw material from which and on which you build the structures of the modern world. And like dirt, data can seem like a limitless, undifferentiated mass. ......一起来看看 《Machine Learning in Action》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具