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实现的基于金山词霸网络翻译的代码
Jan 15 Javascript
javascript setTimeout()传递函数参数(包括传递对象参数)
Apr 07 Javascript
js限制文本框为整数和货币的函数代码
Oct 13 Javascript
鼠标划过实现延迟加载并隐藏层的js代码
Oct 11 Javascript
jquery实现标签上移、下移、置顶
Apr 26 Javascript
jQuery操作dom实现弹出页面遮罩层(web端和移动端阻止遮罩层的滑动)
Aug 25 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
Jun 30 Javascript
关于JavaScript的单双引号嵌套问题
Aug 20 Javascript
微信小程序仿RadioGroup改变样式的处理方案
Jul 13 Javascript
如何用RxJS实现Redux Form
Dec 29 Javascript
jQuery实现可编辑的表格
Dec 11 jQuery
npm ci命令的基本使用方法
Sep 20 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
PHP 截取字符串函数整理(支持gb2312和utf-8)
2010/02/16 PHP
js常用函数 不错
2006/09/08 Javascript
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
根据选择不同的下拉值出现相对应的文本输入框
2013/08/01 Javascript
js判断运行jsp页面的浏览器类型以及版本示例
2013/10/30 Javascript
JQuery结合CSS操作打印样式的方法
2013/12/24 Javascript
关于JS数组追加数组采用push.apply的问题
2014/06/09 Javascript
一个css与js结合的下拉菜单支持主流浏览器
2014/10/08 Javascript
一个JavaScript防止表单重复提交的实例
2014/10/21 Javascript
JavaScript中三种异步上传文件方式
2016/03/06 Javascript
JavaScript实现字符串与日期的互相转换及日期的格式化
2016/03/07 Javascript
AngularJs  Understanding Angular Templates
2016/09/02 Javascript
jquery中封装函数传递当前元素的方法示例
2017/05/05 jQuery
Vue.js上下滚动加载组件的实例代码
2017/07/17 Javascript
Vue 多层组件嵌套二种实现方式(测试实例)
2017/09/08 Javascript
Vue 中使用vue2-highcharts实现曲线数据展示的方法
2018/03/05 Javascript
[01:38]DOTA2 2015国际邀请赛中国区预选赛 Showopen
2015/06/01 DOTA
Python字符串处理之count()方法的使用
2015/05/18 Python
Python 中的with关键字使用详解
2016/09/11 Python
python图形用户接口实例详解
2019/12/16 Python
python3实现raspberry pi(树莓派)4驱小车控制程序
2020/02/12 Python
python分布式爬虫中消息队列知识点详解
2020/11/26 Python
详解css3自定义滚动条样式写法
2017/12/25 HTML / CSS
HTML5 解析规则分析
2009/08/14 HTML / CSS
澳大利亚自然和有机的健康美容产品一站式商店:Ziani Beauty
2017/12/28 全球购物
欧缇丽加拿大官方网站:Caudalie加拿大
2019/07/18 全球购物
娱乐地球:Entertainment Earth
2020/01/08 全球购物
商得四方公司面试题(gid+)
2014/04/30 面试题
法律六进活动方案
2014/03/13 职场文书
《小猪家的桃花树》教学反思
2014/04/11 职场文书
简爱读书笔记
2015/06/26 职场文书
2016消防宣传标语口号
2015/12/26 职场文书
靠谱的活动总结
2019/04/16 职场文书
Redis读写分离搭建的完整步骤
2021/09/14 Redis
MYSQL如何查看操作日志详解
2022/05/30 MySQL
SQLServer常见数学函数梳理总结
2022/08/05 MySQL