2019 年编写现代 JavaScript 代码的5个小技巧(小结)


Posted in Javascript onJanuary 15, 2019

内容基本是今年从其他大神的文章学习到的东西。分享给大家:

1 Array.includes 与条件判断

一般我们判断或用 ||

// condition
function test(fruit) {
 if (fruit == "apple" || fruit == "strawberry") {
  console.log("red");
 }
}

如果我们有更多水果

function test(fruit) {
 const redFruits = ["apple", "strawberry", "cherry", "cranberries"];

 if (redFruits.includes(fruit)) {
  console.log("red");
 }
}

2 Set 与去重

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。

数组去重

const arr = [3, 5, 2, 2, 5, 5];
const unique = [...new Set(arr)];
// [3,5,2]

Array.from 方法可以将 Set 结构转为数组。我们可以专门编写使用一个去重的函数

function unique(array) {
 return Array.from(new Set(array));
}

unique([1, 1, 2, 3]); // [1, 2, 3]

字符去重

let str = [...new Set("ababbc")].join("");
console.log(str);
// 'abc'

另外 Set 是如此强大,因此使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

3 Map 与字典类型数据

一般而已,JavaScript 实现字典数据是基于 Object 对象。但是 JavaScript 的对象的键只能是字符串。对于编程来说有很多不便。 ES6 提供了 Map 数据结构。它类似于 Object 对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值,字符串、数值、布尔值、数组、对象等等都可以当作键。

const resultMap = new Map()
 .set(-1, {text:'小于',color:'yellow')
 .set(0, {text:'等于',color:'black')
 .set(1, {text:'大于',color:'green')
 .set(null,{text:'没有物品',color:'red'})

let state = resultMap.get(null)
// {text:'没有物品',color:'red'}

Map 的遍历顺序就是插入顺序

const map = new Map([["F", "no"], ["T", "yes"]]);

for (let key of map.keys) {
 console.log(key);
}
// "F"
// "T"

for (let value of map.value()) {
 console.log(value);
}
// "no"
// "yes"

4 函数式的方式处理数据

按照我的理解,函数式编程主张函数必须接受至少一个参数并返回一个值。所以所有的关于数据的操作,都可以用函数式的方式处理。

假设我们有这样的需求,需要先把数组 foo 中的对象结构更改,然后从中挑选出一些符合条件的对象,并且把这些对象放进新数组 result 里。

let foo = [
 {
  name: "Stark",
  age: 21
 },
 {
  name: "Jarvis",
  age: 20
 },
 {
  name: "Pepper",
  age: 16
 }
];

//我们希望得到结构稍微不同,age大于16的对象:
let result = [
 {
  person: {
   name: "Stark",
   age: 21
  },
  friends: []
 },
 {
  person: {
   name: "Jarvis",
   age: 20
  },
  friends: []
 }
];

从直觉上我们很容易写出这样的代码:

let result = [];

//有时甚至是普通的for循环
foo.forEach(function(person){
  if(person.age > 16){
    let newItem = {
      person: person,
      friends: [];
    };
    result.push(newItem);
  }
})

使用函数式的写法,可以优雅得多

let result = foo
 .filter(person => person.age > 16)
 .map(person => ({
  person: person,
  friends: []
 }));

数组求和

let foo = [1, 2, 3, 4, 5];

//不优雅
function sum(arr) {
 let x = 0;
 for (let i = 0; i < arr.length; i++) {
  x += arr[i];
 }
 return x;
}
sum(foo); // => 15

//优雅
foo.reduce((a, b) => a + b); // => 15

5 compose 与函数组合

以下代码称为组合 compose

const compose = function(f, g) {
 return function(x) {
  return f(g(x));
 };
};

由于函数式编程大行其道,所以现在将会在 JavaScript 代码看到大量的箭头()=>()=>()=>的代码。

ES6 版本 compose

const compose = (f, g) => x => f(g(x));

在 compose 的定义中, g 将先于 f 执行,因此就创建了一个从右到左的数据 流。这样做的可读性远远高于嵌套一大堆的函数调用.

我们选择一些函数,让它们结合,生成一个崭新的函数。

reverse 反转列表, head 取列表中的第一个元素;

const head = arr => arr[0];
const reverse = arr => [].concat(arr).reverse();

const last = compose(head, reverse);
last(["jumpkick", "roundhouse", "uppercut"]);
// "uppercut"

但是我们这个这个compose不够完善,只能处理两个函数参数。redux源码有个很完备的compose函数,我们借鉴一下。

function compose(...funcs){
 if (funcs.length === 0){
   return arg => arg
 }

 if (funcs.length === 1 ){
   return funcs[0]
 }

 return funcs.reduce((a,b)=>(...args) => a(b(...args)))
}

有了这个函数,我们可以随意组合无数个函数。现在我们增加需求,组合出一个lastAndUpper函数,内容是先reverse 反转列表, head 取列表中的第一个元素, 最后toUpperCase大写。

const head = arr => arr[0];
const reverse = arr => [].concat(arr).reverse();
const toUpperCase = str => str.toUpperCase();

const last = compose(head, reverse);

const lastAndUpper = compose(toUpperCase, head, reverse,);

console.log(last(["jumpkick", "roundhouse", "uppercut"]));
// "uppercut"
console.log(lastAndUpper(["jumpkick", "roundhouse", "uppercut"]))
// "UPPERCUT"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript prototype,executing,context,closure
Dec 24 Javascript
javascript 文件的同步加载与异步加载实现原理
Dec 13 Javascript
javascript实现存储hmtl字符串示例
Apr 25 Javascript
jquery使用正则表达式验证email地址的方法
Jan 22 Javascript
JavaScript中的分号插入机制详细介绍
Feb 11 Javascript
Javascript实现字数统计
Jul 03 Javascript
jquery自定义插件开发之window的实现过程
May 06 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
May 21 jQuery
详解Vue微信授权登录前后端分离较为优雅的解决方案
Jun 29 Javascript
node app 打包工具pkg的具体使用
Jan 17 Javascript
mpvue微信小程序开发之实现一个弹幕评论
Nov 24 Javascript
JavaScript实现放大镜效果代码示例
Apr 29 Javascript
mock.js实现模拟生成假数据功能示例
Jan 15 #Javascript
详解webpack引入第三方库的方式以及注意事项
Jan 15 #Javascript
JS高阶函数原理与用法实例分析
Jan 15 #Javascript
JS立即执行函数功能与用法分析
Jan 15 #Javascript
vue-cli 目录结构详细讲解总结
Jan 15 #Javascript
webpack file-loader和url-loader的区别
Jan 15 #Javascript
jQuery+vue.js实现的多选下拉列表功能示例
Jan 15 #jQuery
You might like
世界第一个无线广播电台 KDKA
2021/03/01 无线电
PHP 可阅读随机字符串代码
2010/05/26 PHP
set_exception_handler函数在ThinkPHP中的用法
2014/10/31 PHP
zend framework重定向方法小结
2016/05/28 PHP
PHP单例模式简单用法示例
2017/06/23 PHP
Laravel中的chunk组块结果集处理与注意问题
2018/08/15 PHP
TP5框架简单登录功能实现方法示例
2019/10/31 PHP
Javascript select控件操作大全(新增、修改、删除、选中、清空、判断存在等)
2008/12/19 Javascript
解javascript 混淆加密收藏
2009/01/16 Javascript
jquery.boxy插件的iframe扩展代码
2010/07/02 Javascript
Javascript 按位与运算符 (&amp;)使用介绍
2014/02/04 Javascript
jquery实现的网页自动播放声音
2014/04/30 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
2016/01/14 Javascript
jQuery Ajax和getJSON获取后台普通json数据和层级json数据用法分析
2016/06/08 Javascript
解析JavaScript数组方法reduce
2016/12/12 Javascript
Vue实现双向绑定的方法
2016/12/22 Javascript
Vue.js实现表格动态增加删除的方法(附源码下载)
2017/01/20 Javascript
深入nodejs中流(stream)的理解
2017/03/27 NodeJs
关于Vue组件库开发详析
2018/07/01 Javascript
微信小程序实现的日期午别医生排班表功能示例
2019/01/09 Javascript
ES10 特性的完整指南小结
2019/03/04 Javascript
Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)
2019/04/17 Javascript
js实现炫酷光感效果
2020/09/05 Javascript
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
浅析Python中的序列化存储的方法
2015/04/28 Python
Python插件virtualenv搭建虚拟环境
2017/11/20 Python
Python3连接SQLServer、Oracle、MySql的方法
2018/06/28 Python
VPS CENTOS 上配置python,mysql,nginx,uwsgi,django的方法详解
2019/07/01 Python
三星英国官网:Samsung英国
2018/09/25 全球购物
Yahoo-PHP面试题1
2016/07/20 面试题
Tomcat Mysql datasource数据源配置
2015/12/28 面试题
《老山界》教学反思
2014/04/08 职场文书
授权委托书格式范文
2014/08/02 职场文书
医院深入开展党的群众路线教育实践活动实施方案
2014/08/27 职场文书
2014年党风廉政建设工作总结
2014/11/19 职场文书
MySQL数据库如何给表设置约束详解
2022/03/13 MySQL