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 相关文章推荐
jQuery实现用方向键控制层的上下左右移动
Jan 13 Javascript
input输入框的自动匹配(原生代码)
Mar 19 Javascript
js function定义函数的几种不错方法
Feb 27 Javascript
js调试系列 初识控制台
Jun 18 Javascript
js中函数声明与函数表达式
Jun 03 Javascript
JS绘制生成花瓣效果的方法
Aug 05 Javascript
谈一谈javascript闭包
Jan 28 Javascript
JavaScript中英文字符长度统计方法示例【按照中文占2个字符】
Jan 17 Javascript
详解win7 cmd执行vue不是内部命令的解决方法
Jul 27 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
Sep 15 Javascript
js遍历详解(forEach, map, for, for...in, for...of)
Aug 28 Javascript
JavaScript进阶(三)闭包原理与用法详解
May 09 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
解决Codeigniter不能上传rar和zip压缩包问题
2014/03/07 PHP
php数组查找函数总结
2014/11/18 PHP
PHP实现的MD5结合RSA签名算法实例
2017/10/07 PHP
PHP实现基于栈的后缀表达式求值功能
2017/11/10 PHP
jQuery的deferred对象详解
2014/11/12 Javascript
JavaScript中用于四舍五入的Math.round()方法讲解
2015/06/15 Javascript
快速获取/设置iframe内对象元素的几种js实现方法
2016/05/20 Javascript
jquery实现简单Tab切换菜单效果
2020/07/17 Javascript
AngularJS使用ng-options指令实现下拉框
2016/08/23 Javascript
js 弹出虚拟键盘修改密码的简单实例
2016/10/10 Javascript
功能强大的jquery.validate表单验证插件
2016/11/07 Javascript
SelecT下拉框选中和取值的解决方法
2016/11/22 Javascript
原生JS实现幻灯片
2017/02/22 Javascript
node.js学习之断言assert的使用示例
2017/09/28 Javascript
详解redux异步操作实践
2018/08/15 Javascript
Vue模拟数据,实现路由进入商品详情页面的示例
2018/08/31 Javascript
JSONP原理及应用实例详解
2018/09/13 Javascript
JavaScript将数组转换为链表的方法
2020/02/16 Javascript
vue keep-alive实现多组件嵌套中个别组件存活不销毁的操作
2020/10/30 Javascript
python在Windows8下获取本机ip地址的方法
2015/03/14 Python
Python 爬虫模拟登陆知乎
2016/09/23 Python
对Python3+gdal 读取tiff格式数据的实例讲解
2018/12/04 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
2018/12/24 Python
Python Web程序搭建简单的Web服务器
2019/07/31 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
wxpython实现按钮切换界面的方法
2019/11/19 Python
python绘制玫瑰的实现代码
2020/03/02 Python
Python tkinter 下拉日历控件代码
2020/03/04 Python
Python参数传递对象的引用原理解析
2020/05/22 Python
Python实现七个基本算法的实例代码
2020/10/08 Python
Auchan Direct波兰:欧尚在线杂货店
2016/10/19 全球购物
意大利奢侈品零售商:ilDuomo Novara
2019/09/11 全球购物
局域网定义和特性
2016/01/23 面试题
金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-> (一千零一拾一元整)输出
2015/05/29 面试题
大学生暑假实习总结
2015/07/13 职场文书
2019入党申请书格式
2019/06/25 职场文书