1:代码复用 - 适用于多表单验证
/* 代码复用:适用于多表单验证 */// 验证规则配置const scheme = {first: {required: true,},second: {required: true,},last: {required: false}}// 验证函数const validate = (scheme, values) => {for (field in scheme) {if (scheme[field].required) {if (!values[field]) {return false;}}}return true;};console.log(validate(scheme, { first: 'Bruce' })); // falseconsole.log(validate(scheme, { first: 'Bruce', second: 'Wayne' })); // true
2:函数参数中解构嵌套对象
/* 函数参数中解构嵌套对象 */const car = {model: 'bmw 2020',engine: {v6: true,turbo: true,vin: 123456}};const modelAndVin = ({ model, engine: { vin } }) => {console.log(`model: ${model} vin: ${vin}`);};
3:使用解构删除不必要的属性
有时候你不希望保留某些对象属性,也许是因为它们包含敏感信息或仅仅是太大了(just too big)。你可能会枚举整个对象然后删除它们,但实际上只需要简单的将这些无用属性赋值给变量,然后把想要保留的有用部分作为剩余参数就可以了。
下面的代码里,我们希望删除_internal和tooBig参数。我们可以把它们赋值给internal和tooBig变量,然后在cleanObject中存储剩下的属性以备后用。
/* 3: 使用解构删除不必要的属性 */let { _internal, tooBig, ...cleanObject } = { el1: 1, _internal: "secret", tooBig: {}, el2: 2, el3: 3 };console.log(cleanObject); // {el1: 1 , el2: 2 , el3: 3 }
4:数组对象解构
数组也可以对象解构,可以方便的获取数组的第n个值
/* 4:数组对象解构 */const csvFileLine = "1997,John Doe,US,john@doe.com,New York";const { 2: country, 4: state } = csvFileLine.split(',');console.log(country, state); // US, New York
5: 数组平铺到指定深度
const flatten = (arr, depth = 1) => {return depth != 1 ?arr.reduce((a, v) =>a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), []) :arr.reduce((a, v) => a.concat(v), []);};console.log(flatten([1, [2], 3, 4])); // [1, 2, 3, 4]console.log(flatten([1, [2, [3, [4, 5], 6], 7], 8], 2)); // [1, 2, 3, [4, 5], 6, 7, 8]
6:使用解构来交换参数值
let param1 = 1;let param2 = 2;[param1, param2] = [param2, param1];console.log(param1); // 2console.log(param2); // 1
7:统计数组中相同项的个数
const cars = ['BMW', 'Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];const carsObj = cars.reduce((obj, name) => {obj[name] = obj[name] ? ++obj[name] : 1;return obj;}, {});console.log(carsObj); // {BMW: 2, Benz: 2, Tesla: 1, Toyota: 1}
8:数值补0操作
const addZero1 = (num, len = 2) => (`0${num}`).slice(-len);const addZero2 = (num, len = 2) => (`${num}`).padStart(len, 0);console.log(addZero1(3)); // 03
console.log(addZero2(32, 4)); // 0032
9:将数值精确到指定位数
const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);console.log(round(1.345, 2)); // 1.35
console.log(round(1.345, 1)); // 1.3
10:一次性函数(适用于那些只需要执行一次的初始化代码)
var sca = function () {console.log('msg');sca = function () {console.log('foo');}
}sca() // msg
sca() // foo
sca() // foo
11: 隐士返回值
/** 返回值使我们通常用来返回函数最终结果的关键字。只有一个语句的箭头函数, 可以隐士返回结果(函数必须省略{},以便省略返回关键字) **//** 要返回多行语句(例如对象文本),需要使用() 而不是{}来包裹函数体。这样可以确保代码以单个语句的形式进行求值 **/function calcCircumFerence(diameter) {return Math.PI * diameter;}// 简写为calcCircumFerence = diameter => (Math.PI * diameter);
12:函数参数默认值
const func = (l, m = 3, n = 4) => (l * m * n);console.log(func(2)); // 24
13: 判断奇数偶数(!! (num & 1))
console.log(!!(5 & 1)); // trueconsole.log(!!(-5 & 1)); // trueconsole.log(!!(6 & 1)); // falseconsole.log(!!(-6 & 1)); // false
14: 取整
console.log(1.3 | 0); // 1console.log(-1.9 | 0); // -1
15: 双位运算符
/** 可以使用双位操作符来代替整数的 Math.floor(), 代替负数的 Math.ceil()。双否定位操作符的优势在于它执行相同的操作运行速度更快 **/console.log(~~4.5); // 4console.log(Math.floor(4.5)); // 4console.log(Math.ceil(4.5)); // 5console.log(~~-4.5); // -4console.log(Math.floor(-4.5)); // -5console.log(Math.ceil(-4.5)); // -4
16:数据类型判断
Object.prototype.toString.call() 返回的数据格式为[object Object]类型,然后再用slice截取第8位到倒数一位,
得到结果为 Object
/* Object.prototype.toString.call() 返回的数据格式为[object Object]类型,然后再用slice截取第8位到倒数一位,得到结果为 Object */const _toString = Object.prototype.toString;function toRawType(value) {return _toString.call(value).slice(8, -1);}console.log(toRawType({})); // Objectconsole.log(toRawType([])); // Arrayconsole.log(toRawType(true)); // Booleanconsole.log(toRawType(undefined)); // Undefinedconsole.log(toRawType(null)); // Nullconsole.log(toRawType(function () { })); // Function
17:数据求和
/** 数组求和 **/const arr = [1, 2, 3, 4, 5]// const sum = arr.reduce((pre, item) => {// return pre + item// }, 0)// 简写const sum = arr.reduce((pre, item) => pre + item, 0);console.log(sum) // 15