前言
如果想要写出易读性高,可维护性强且优美的代码,那以下这些知识背景必不可少。
一、数组/对象方法认识及举例
1. 常用的重要Array方法
- join(), concat()
// join用法举例:当后端返回了一个数组,要求前端用字符串展示时
const namesArr = ['Jack', 'Linda', 'Justin', 'David'];
const namesStr = namesArr.join(',');
const namesStrExample = namesArr.join('-');
console.log(namesStr); // Jack,Linda,Justin,David
console.log(namesStrExample); // Jack-Linda-Justin-David
// concat用法举例:
// 当后端先返回了一个数组,后又返回了另一个数组,要求前端拼接,不需要循环arr2元素去push到arr1,可以concat拼接
const arr1 = ['Jack', 'Linda'];
const arr2 = ['Justin', 'David'];
const arr3 = arr1.concat(arr2);
console.log(arr3); // ['Jack', 'Linda', 'Justin', 'David']
- slice(start, end),splice(start, deleteCount, item1, item2, itemN)
// slice(start,end)用法举例:只挑选数组里从索引start~(end-1)的值
// 不影响原数组!!!
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// Expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// Expected output: Array ["bison", "camel", "duck", "elephant"]
console.log(animals.slice(-2)); // -2+animals.length
// Expected output: Array ["duck", "elephant"]
console.log(animals.slice(2, -1)); // -1+animals.length
// Expected output: Array ["camel", "duck"]
console.log(animals.slice());
// Expected output: Array ["ant", "bison", "camel", "duck", "elephant"]
// splice(start, deleteCount, item1, item2, itemN)用法举例:
// 需要在数组里删除索引为start, deleteCount个元素,并新增item1~itemN个元素
// 影响原数组!!!
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb'); // 在索引为1的地方,删除0个元素,新增'Feb'元素
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, 'May'); // 在索引为4的地方替换一个元素
console.log(months);
// Expected output: Array ["Jan", "Feb", "March", "April", "May"]
- sort(), reverse()
// sort用法举例:
// 影响原数组!!!
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// Expected output: Array ["Dec", "Feb", "Jan", "March"]
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// Expected output: Array [1, 100000, 21, 30, 4]
// reverse用法举例:
// 影响原数组!!!
const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);
// Expected output: "array1:" Array ["one", "two", "three"]
const reversed = array1.reverse();
console.log('reversed:', reversed);
// Expected output: "reversed:" Array ["three", "two", "one"]
- indexOf(searchElement, fromIndex), includes(searchElement, fromIndex)
// indexOf用法举例
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('bison'));
// Expected output: 1
// Start from index 2
console.log(beasts.indexOf('bison', 2));
// Expected output: 4
console.log(beasts.indexOf('giraffe'));
// Expected output: -1
// includes用法举例
const array1 = [1, 2, 3];
console.log(array1.includes(2));
// Expected output: true
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// Expected output: true
console.log(pets.includes('at'));
// Expected output: false
- filter((element, index, array) => { … }), find((element, index, array) => { … })
// filter用法举例:返回所有匹配的值
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]
// find用法举例:返回第一个匹配的值
const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found);
// Expected output: 12
- every((element, index, array) => { … }), some((element, index, array) => { … })
// every用法举例:所有元素都符合条件才返回true
const isBelowThreshold = (currentValue) => currentValue < 40;
const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold));
// Expected output: true
// some用法举例: 只要有一个满足条件就返回true
const array = [1, 2, 3, 4, 5];
// Checks whether an element is even
const even = (element) => element % 2 === 0;
console.log(array.some(even));
// Expected output: true
- forEach((element, index, array) => { … }),map((element, index, array) => { … })
// forEach用法举例:循环对每个元素进行一些处理
// 不影响原数组
// 不能用break, continue跳出循环
const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element+1));
// Expected output: "a1"
// Expected output: "b1"
// Expected output: "c1"
// map用法举例: 在原数组上做处理,返回一个新数组,不影响原数组
const array1 = [1, 4, 9, 16];
// Pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// Expected output: Array [2, 8, 18, 32]
console.log(array1)
// Expected output: Array [1, 4, 9, 16]
- entries(), keys(), values()
// entries用法举例: 索引与值的数组对,[index, value]
const a = ["a", "b", "c"];
for (const [index, element] of a.entries()) {
console.log(index, element);
}
// 0 'a'
// 1 'b'
// 2 'c'
// keys用法举例: 索引
const b = ['d','f','g'];
for (const key of b.keys()) {
console.log(key);
}
// 0
// 1
// 2
// values用法举例:值
const c = ['add', 'edit', 'delete'];
for (const value of c.values()) {
console.log(value);
}
// "add"
// "edit"
// "delete"
- reduce((accumulator, currentValue, currentIndex, array) => { … }, initialValue)
// reduce用法举例:
const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue
);
console.log(sumWithInitial);
// Expected output: 10
2. 常用的遍历方法
- 数组常用遍历方法
- for 循环
const arr = [3, 5, 8, 13];
for (const i = 0, l = arr.length; i<l; i++) {
console.log(arr[i]);
}
// 3
// 5
// 8
// 13
- for of 循环
// for of 可以循环Arry, Map, Set, String等等
const array1 = ['a', 'b', 'c'];
for (const element of array1) {
console.log(element);
}
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
let iterable = "boo";
for (let value of iterable) {
console.log(value);
}
// "b"
// "o"
// "o"
- forEach/map 循环
区别:map会返回一个新对象,forEach返回undefined
- 对象常用遍历方法
- for in 循环
// for...in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()和for...of
// for...in以任意顺序迭代对象
var obj = {a:1, b:2, c:3};
for (let prop in obj) {
console.log("obj." + prop + " = " + obj[prop]);
}
// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
- Object.keys()/Object.values()
- Object.getOwnPropertyNames(obj)
var obj = {'0':'a','1':'b','2':'c'};
Object.getOwnPropertyNames(obj).forEach(function(key){
console.log(key,obj[key]);
});
- Reflect.ownKeys(obj)
var obj = {'0':'a','1':'b','2':'c'};
Reflect.ownKeys(obj).forEach(function(key){
console.log(key,obj[key]);
});
3. 常用的一些美化方法
- 利用数组方式优化switch case/if else
举例:1-7的数字变量,转换成中文的星期几
// 优化前
let n = someDay;
let result;
switch(n) {
case 1:
result = '星期一';
break;
case 2:
result = '星期二';
break;
...
}
// 优化后
const week = ['一','二','三','四','五','六','日'];
let n = someDay;
return `星期${week[someDay-1]}`;
- 利用字面量对象方式优化if else
// 优化前
if(obj.type === 'number') {
return formatNumber(obj.value)
} else if (obj.type === 'percentage') {
return formatPercentage(obj.value)
} else if (obj.type === 'date') {
return formatDate(obj.value)
} else if (obj.type === 'enum') {
return formatEnum(obj.value)
}
// 优化后
const typeFunctionMap = {
'number': 'formatNumber',
'percentage': 'formatPercentage',
'date': 'formatDate',
'enum': 'formatEnum'
};
return typeFunctionMap[obj.type](obj.value);
- Early Return,减少if else嵌套
// bad
function getSomething() {
const result = axios.get(...);
if (result.success) {
const length = result.data.length;
if (length) {
const response = axios.post(...);
if (response.success) {
// do somthing...
}
}
}
}
// good
function getSomething() {
const result = axios.get(...);
if (!result?.success) {return;}
const length = result.data?.length;
if (!length) {return;}
const response = axios.post(...);
if (!response?.success) {
// do something...
}
}
- 默认值设置
// es5
let num = num || 1
// es5以上
let num = num ?? 1
- 使用Array.some()和Array.every()处理部分/全部满足条件
- 减少方法传参数量
// bad
function example(a, b, c, d) {};
example(1,2,3,4);
// good
const obj = {a:1, b:2, c:3, d:4};
function example({a, b, c, d}) {};
example(obj)
二、ECMAScript新特性
新特性文档:www.w3schools.com/js/js_es6.a…
三、lodash重要方法认识举例
中文文档:www.lodashjs.com/
以下是一些场景举例
- 一个对象数组,需要根据对象里的某个字段给数组去重
import {uniqBy} from 'lodash';
const array = [
{id: 1, desc: 'the number one', fId: 'f1'},
{id: 1, desc: 'the number one', fId: 'f2'},
{id: 2, desc: 'the number two', fId: 'f3'},
{id: 2, desc: 'the number two', fId: 'f4'}
];
const result = uniqBy(arr, 'id');
console.log(result);
// [{id: 1, desc: 'the number one', fId: 'f1'}, {id: 2, desc: 'the number two', fId: 'f3'}]
- 一个用户表单界面,只有满足两种条件才可点击下一步:全部填或者全部不填
import {compact} from 'lodash';
const form = {
userFirstName: '',
userLastName: '',
userEmail: '',
userPhoneNumber: ''
};
const result = compact(Object.values(form));
if (result?.length && result.length !== 4) {
return;
}
nextStep();
- 从一个对象中挑选一些字段
import {pick} from 'lodash';
const obj = {
'userId': 'u1',
'userName': 'Cherry',
'userPhoneNumber': '1350987909',
'otherInfo1': '',
'otherInfo2': ''
}
console.log(pick(obj, ['userId', 'userName', 'userPhoneNumber']));
// {"userId": "u1", "userName": "Cherry", "userPhoneNumber": "1350987909"}
四、script举例优化
-
脚本:1f37e3dd-a7e3-2591-aab9-39ffaea7a284
- 目前写法
function selectCompany(page) { let text = page.text.replace(/\s/g, '').toLowerCase(); if (text.indexOf('edmondbranch,oklahomacityabstract') > -1) { return getJsonEdmondBranchOklahomaCityAbstract(); } if (text.indexOf('chicagotitleandtrustcompany') > -1) {//Done! At 2021/11/15 by Zoie return getChicagoTitleandTrustCompany(); } if (text.indexOf('chicagotitlecompany') > -1) {//Done! At 2021/11/16 by Zoie return getchicagotitlecompany(); } if (text.indexOf('a.settlementstatement') > -1) {//Done! At 2021/11/22 by Zoie return getASettlementStatement(); } if (text.indexOf('cwtitle') > -1) {//Done! At 2021/11/11 by Zhiqin return getCwTitle(); } // ... return false; }-
优化后
function selectCompany(page) { let text = page.text.replace(/\s/g, '').toLowerCase(); const objArr = [{ word: 'edmondbranch,oklahomacityabstract', fun: 'getJsonEdmondBranchOklahomaCityAbstract' }, { word: 'chicagotitleandtrustcompany', fun: 'getChicagoTitleandTrustCompany' }, { word: 'chicagotitlecompany', fun: 'getchicagotitlecompany' }, { word: 'a.settlementstatement', fun: 'getASettlementStatement' }, { word: 'cwtitle', fun: 'getCwTitle' }]; for (const item of objArr) { if (text.includes(item.word)) { return item['fun'](); } } return false; }