这篇文章主要记录一下平时自己实践得到的, 博客中学习的以及在一些项目源码中看到的 javascript 技巧。有些东西可以说是奇淫技巧,有些可能是 ES6+ 中一些比较具有实用性的新语法。
&& 和 || 的妙用有时候我们需要在某个函数或变量为 true 时执行另外一个函数。例如:
上面的 if 语句可以使用 && 直接简写为:
如果还要在 task1 失败后执行 task3, 可以使用:
本质上还是利用了 && 和 || 的短路特性。
下面展示一个我最近使用 react hooks 开发的项目的的一个代码片段:
函数默认值ES5 版本使用短路或操作符来设置函数默认值的方式其实很常见。但是有一些坑,下面展示的代码中当默认值参数为一个数字时,传参为 0 还是会使用默认值,必须对 y 为 0 的时候单独进行判断。
ES6 版本ES6 在语法层面提供的默认值语法就靠谱的多了
类数组转数组类数组指的是像 arguments ,jquery 对象一样可以使用下标访问还有 length 属性的和数组很像但并不是数组的一类对象。
类数组没有 slice, map 等集合函数,这也是为什么我们有时候需要将类数组转换成数组的原因。
ES5 中的转换方法将 Array 原型中的 slice 方法绑定到 arguments 对象上调用,并且不传参数目的为了让其返回所有的元素。
ES6 中的转换方法ES6 将类数组转换成数组的方法多一些。
使用扩展运算符
使用 Array.from
构造一个连续整数的数组这里就直接给出我觉得最好的方法了
函数参数使用结构赋值函数参数比较多的时候我们往往会让参数直接接受一个配置对象。但是使用对象参数我们无法设置默认值,在函数体中使用对象参数时还需要使用通过对象参数来访问,当访问次数比较多或者嵌套比较深就会觉得不方便。在函数参数中使用结构赋值就解决了上面的问题。
// 必须给对象参数设置默认值, 不然传参数时因为没有解构对象会报错
使用 !! 将其它类型转换成 bool 型
JSON.stringify深度克隆使用先序列化再反序列化这种方式来深度克隆对象在一般情况下很方便,缺点就是无法克隆函数以及继承的属性。
如果还幺克隆函数属性,推荐使用 lodash 的 cloneDeep。
使用第二个和第三参数JSON.stringify 的第二个参数是用来对属性设置进行处理的,第三个测试指定输出的 json 字符串的缩进长度,可以传数字也可以传字符串。
优雅的遍历对像使用解构赋值和 Object.entries。
清空数组的最快方法
判断一个整数是否是 -1
立即执行函数立即执行函数可以让我们的代码中的变量不污染外部变量,常见的使用方式是像下面这样的。
使用 set 来对数组去重复
使用 reduce 连乘或连加
更多技巧待我想起来了再补充...
文章转载自:https://juejin.cn/post/6844903812763746317
&& 和 || 的妙用有时候我们需要在某个函数或变量为 true 时执行另外一个函数。例如:
[JavaScript]
纯文本查看
复制代码
1 2 3 4 5 6 7 | const task1 = () => { console.log('执行 task1'); return Math.random() >= 0.5;}const task2 = () => console.log('task1 执行成功后执行 task2');if (task1()) task2(); |
上面的 if 语句可以使用 && 直接简写为:
[JavaScript]
纯文本查看
复制代码
1 | task1() && task2(); |
如果还要在 task1 失败后执行 task3, 可以使用:
[JavaScript]
纯文本查看
复制代码
1 2 | const task3 = () => console.log('task1 执行失败后执行 task3');task1() && task2() || task3(); |
本质上还是利用了 && 和 || 的短路特性。
下面展示一个我最近使用 react hooks 开发的项目的的一个代码片段:
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 | const ProfileItem = (props) => { const { name, value, render } = props; return ( <div className="profile-item"> <span className="item-name">{name}</span> <form action=""> {/* 根据是否有 render 这个 props 来返回不同的内容 */} {render && render(props) || <SimpleProfileItemContent value={value}/>} </form> </div> )} |
函数默认值ES5 版本使用短路或操作符来设置函数默认值的方式其实很常见。但是有一些坑,下面展示的代码中当默认值参数为一个数字时,传参为 0 还是会使用默认值,必须对 y 为 0 的时候单独进行判断。
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | const pow = (x, y) => { y = y || 2; let result = 1; for (let i = 0, max = y; i < max; i++) { result *= x; } return result;}console.log(pow(2)); // => 4console.log(pow(2, 3)); // => 8// 当 y 传值为 0 时, y 取值 2console.log(pow(2, 0)); // => 4 |
ES6 版本ES6 在语法层面提供的默认值语法就靠谱的多了
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 | const pow = (x, y=2) => { let result = 1; for (let i = 0, max = y; i < max; i++) { result *= x; } return result;}console.log(pow(2)); // => 4console.log(pow(2, 3)) // => 8console.log(pow(2, 0)); // => 1 |
类数组转数组类数组指的是像 arguments ,jquery 对象一样可以使用下标访问还有 length 属性的和数组很像但并不是数组的一类对象。
类数组没有 slice, map 等集合函数,这也是为什么我们有时候需要将类数组转换成数组的原因。
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | function func() { for (let i = 0, max = arguments.length; i < max; i++) { console.log(arguments[i]); } console.log(Array.isArray(arguments)); // => false // 类数组没有 slice, forEach, map 等集合函数 console.log(arguments.slice === undefined); // => true}func('Google', 'facebook', 'Microsoft'); // => // Google// facebook// Microsoft |
ES5 中的转换方法将 Array 原型中的 slice 方法绑定到 arguments 对象上调用,并且不传参数目的为了让其返回所有的元素。
[JavaScript]
纯文本查看
复制代码
1 2 3 4 5 6 | function func() { const array = Array.prototype.slice.call(arguments); console.log(array.slice(0, 1));}func('Google', 'facebook', 'Microsoft'); // => [ 'Google' ] |
ES6 中的转换方法ES6 将类数组转换成数组的方法多一些。
使用扩展运算符
[JavaScript]
纯文本查看
复制代码
1 2 3 4 5 | function func() { console.log([...arguments])}func('Google', 'facebook', 'Microsoft'); // [ 'Google', 'facebook', 'Microsoft' ] |
使用 Array.from
[JavaScript]
纯文本查看
复制代码
1 2 3 4 5 | function func() { console.log(Array.from(arguments))}func('Google', 'facebook', 'Microsoft'); // [ 'Google', 'facebook', 'Microsoft' ] |
构造一个连续整数的数组这里就直接给出我觉得最好的方法了
[JavaScript]
纯文本查看
复制代码
1 2 3 | // 输出 2 开始连续的8个整数const array = Array.from({ length: 8}).map((ele, index) => index + 2);console.log(array); // => [ 2, 3, 4, 5, 6, 7, 8, 9 ] |
函数参数使用结构赋值函数参数比较多的时候我们往往会让参数直接接受一个配置对象。但是使用对象参数我们无法设置默认值,在函数体中使用对象参数时还需要使用通过对象参数来访问,当访问次数比较多或者嵌套比较深就会觉得不方便。在函数参数中使用结构赋值就解决了上面的问题。
// 必须给对象参数设置默认值, 不然传参数时因为没有解构对象会报错
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 | const getUsers = ({ offset=0, limit=1, orderBy="salary"}={}) => { // 根据条件查询数据库返回用户数据 console.log({ offset, limit, orderBy });}getUsers({ offset: 10, limit: 20,orderBy: 'age' }); // => { offset: 10, limit: 20, orderBy: 'age' }getUsers();// => { offset: 0, limit: 1, orderBy: 'salary' } |
使用 !! 将其它类型转换成 bool 型
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 | console.log(!!{}); // trueconsole.log(!!0); // falseconsole.log(!![]); // trueconsole.log(!!undefined); // falseconst httpGet = (url, retry) => { if (!!retry) { // 超时重发 }} |
JSON.stringify深度克隆使用先序列化再反序列化这种方式来深度克隆对象在一般情况下很方便,缺点就是无法克隆函数以及继承的属性。
如果还幺克隆函数属性,推荐使用 lodash 的 cloneDeep。
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 | const me = { name: 'lyreal666', age: 23, speak() { console.log(`Hello, I'm ly!`); }}const clonedMe = JSON.parse(JSON.stringify(me));console.log(clonedMe); // => { name: 'lyreal666', age: 23 }console.log(clonedMe.speak === undefined); // => true |
使用第二个和第三参数JSON.stringify 的第二个参数是用来对属性设置进行处理的,第三个测试指定输出的 json 字符串的缩进长度,可以传数字也可以传字符串。
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | const me = { name: 'lyreal666', age: 23, speak() { console.log(`Hello, I'm ly!`); }}const jsonStr = JSON.stringify(me, (key, value) => key === 'name' ? '老余' : value, 2);console.log(jsonStr);/* =>{ "name": "老余", "age": 23}*/ |
优雅的遍历对像使用解构赋值和 Object.entries。
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | const me = { name: 'lyreal666', age: 23, speak() { console.log(`Hello, I'm ly!`); }}for (const [key, value] of Object.entries(me)) { console.log(`${key}: ${value}`);}/* =>name: lyreal666age: 23speak: speak() { console.log(`Hello, I'm ly!`); }*/ |
清空数组的最快方法
[JavaScript]
纯文本查看
复制代码
1 2 3 | const array = [1, 2, 3, 4];array.length = 0;console.log(array); // => [] |
判断一个整数是否是 -1
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 11 12 | // ~ 操作符的运算规律可以简单记作将加一的结果取反console.log(~1); // => -2console.log(~0); // => -1console.log(~(-3)); // => 2console.log(~(-1)); // => 0const number = -2;// 判断一个数是否为 -1if (!~number) { // 当 number 是 -1 的操作...} |
立即执行函数立即执行函数可以让我们的代码中的变量不污染外部变量,常见的使用方式是像下面这样的。
[JavaScript]
纯文本查看
复制代码
01 02 03 04 05 06 07 08 09 10 | // 使用括号将函数括起来调用(function(window, $) { // 内部代码}) (window, jQuery)复制代码更优雅的方式是下面这种,事实上很多其它的算术运算符比如 +, -, *, ~ 等也是可以的,! function(window, $) { // 内部代码} (window, jQuery) |
[JavaScript]
纯文本查看
复制代码
1 | console.log([...new Set([1, 3, 1, 2, 2, 1])]); // => [ 1, 3, 2 ] |
使用 reduce 连乘或连加
[JavaScript]
纯文本查看
复制代码
1 2 3 4 5 6 | const array = [ 1, 2, 3, 4];// 连乘console.log(array.reduce((p, c) => p + c)); // => 10// 连加console.log(array.reduce((p, c) => p * c)); // => 24 |
更多技巧待我想起来了再补充...
文章转载自:https://juejin.cn/post/6844903812763746317