js中的小技巧

1. string 转换成数字

  • 可以用 *1 转数字
  • 常用: 也可以使用+来转化字符串为数字
2. 使用Boolean过滤数组中的所有假值
把Boolean构造函数当做回调参数传入,遍历时的每一项又传入Boolean。

const compact = arr => arr.filter(Boolean); compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34])

3. 双位运算符 ~~
可以使用双位操作符来替代 Math.floor()。双否定位操作符的优势在于它执行相同的操作运行速度更快。
Math.floor(4.9) === 4//true // 简写为: ~~4.9 === 4//true

不过要注意,对整数来说 ~~ 运算结果与 Math.floor() 运算结果相同,而对于负数来说不相同:
~~4.5// 4 Math.floor(4.5)// 4 ~~-4.5// -4 Math.floor(-4.5)// -5

4. 取整 | 0
1.3 | 0// 1 -1.9 | 0// -1'1.5' | 0// 1 '-1.2' | 0// -1

5. 字符串比较时间先后
var a = "2014-08-08"; var b = "2014-09-09"; console.log(a > b, a < b); // false true console.log("21:00" < "09:10"); // false console.log("21:00" < "9:10"); // true时间形式注意补0

注意:因为字符串比较大小是按照字符串从左到右每个字符的charCode来的,但所以特别要注意时间形式注意补0
6. 精确到指定位数的小数
将数字四舍五入到指定的小数位数。使用 Math.round() 和模板字面量将数字四舍五入为指定的小数位数。 省略第二个参数 decimals ,数字将被四舍五入到一个整数。
const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`) round(1.345, 2)// 1.35 round(1.345, 1)// 1.3

7. 数字补0操作
有时候比如显示时间的时候有时候会需要把一位数字显示成两位,这时候就需要补0操作,可以使用slice和string的padStart方法
const addZero1 = (num, len = 2) => (`0${num}`).slice(-len) // ES6 字符串补位方法 const addZero2 = (num, len = 2) => (`${num}`).padStart( len, '0') addZero1(3)// 03 addZero2(32,4)// 0032

8. Object [key]
虽然将 foo.bar 写成 foo ['bar'] 是一种常见的做法,但是这种做法构成了编写可重用代码的基础。许多框架使用了这种方法,比如element的表单验证。
请考虑下面这个验证函数的简化示例:
function validate(values) { if(!values.first) return false; if(!values.last) return false; return true; }console.log(validate({first: 'Bruce',last: 'Wayne'})); // true

上面的函数完美的完成验证工作。但是当有很多表单,则需要应用验证,此时会有不同的字段和规则。如果可以构建一个在运行时配置的通用验证函数,会是一个好选择。
// object validation rules const schema = { first: { required: true }, last: { required: true } }// universal validation function const validate = (schema, values) => { for (field in schema) { if (schema[field].required) { if (!values[field]) { return false; } } }return true; }console.log(validate(schema, {first:'Bruce'})); // false console.log(validate(schema, {first:'Bruce',last:'Wayne'})); // true

现在有了这个验证函数,我们就可以在所有窗体中重用,而无需为每个窗体编写自定义验证函数。
9. reduce方法同时实现map和filter
假设现在有一个数列,你希望更新它的每一项(map的功能)然后筛选出一部分(filter的功能)。如果是先使用map然后filter的话,你需要遍历这个数组两次。 在下面的代码中,我们将数列中的值翻倍,然后挑选出那些大于50的数。
const numbers = [10, 20, 30, 40]; const doubledOver50 = numbers.reduce((finalList, num) => { num = num * 2; if (num > 50) { finalList.push(num); } return finalList; }, []); doubledOver50; // [60, 80]

10. 统计数组中相同项的个数
很多时候,你希望统计数组中重复出现项的个数然后用一个对象表示。那么你可以使用reduce方法处理这个数组。
下面的代码将统计每一种车的数目然后把总数用一个对象表示。
let cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota']; let carsObj = cars.reduce((obj, name) => { obj[name] = obj[name] ? ++obj[name] : 1; return obj; }, {}); carsObj; // { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }

11. 使用解构来交换参数数值
let param1 = 1; let param2 = 2; [param1, param2] = [param2, param1];

12. 接收函数返回的多个结果
在下面的代码中,我们从/post中获取一个帖子,然后在/comments中获取相关评论。由于我们使用的是async/await,函数把返回值放在一个数组中。而我们使用数组解构后就可以把返回值直接赋给相应的变量。
async function getFullPost(){ return await Promise.all([ fetch('/post'), fetch('/comments') ]); } const [post, comments] = getFullPost();

13. 平铺多维数组
let arr = [1, 2, [3, 4], [5,6]]; let result = [].concat(...arr); console.log(result) // [1,2,3,4,5,6]

【js中的小技巧】以上方法只适用于二维数组,如果是二维以上数组,通过递归实现
function spread(arr) { let result = [].concat(...arr); return result.some(item => Array.isArray(item)) ? spread(result) : result; }

14. 格式化JSON代码
let obj = { name: 'jack', age: 12, skill: ['play', 'song'] } console.log(JSON.stringify(obj, null, 4)); { "name": "jack", "age": 12, "skill": [ "play", "song" ] }

15. 整数转千分位三种方式
一、只转整数部分,如果有小数,只保留三位
  1. 方式1:
const number = 1234567890 const nf = new Intl.NumberFormat('us') nf.format(number) //如果有小数,最多保留三位小数 // 1,234,567,890 typeof nf.format(number) // string

  1. 方式2:
number.toLocaleString('us') // 1,234,567,890

二、会把小数也转成千分位
// 会把小数为也转成千分位 const reg = /(\d{1,3})(?=(?:\d{3})+(?!\d))/g; // 如果有小数,则只转小数位 const reg1 =/(\d)(?=(\d{3})+$)/g; number.toString().replace(reg, '$1,') // 1,234,567,890

三、只转整数部分,小数位不转
  1. 方式1:
function sep(n) { let [i, c] = n.toString().split(/(\.\d+)/) return i.split('').reverse().map((c, idx) => (idx+1) % 3 === 0 ? ',' + c: c).reverse().join('').replace(/^,/, '') + c }

  1. 方式2:
function sep2(n){ let str = n.toString() str.indexOf('.') < 0 ? str+= '.' : void 0 return str.replace(/(\d)(?=(\d{3})+\.)/g, '$1,').replace(/\.$/, '') }

16. 获取时间戳的方式
  1. Date.parse()
// 返回自定义时间戳 Date.parse('2017/03/19') // 返回当前时间的事件戳 Date.parse(new Date())

  1. Date.getTime()
new Date().getTime()

  1. +new Date()
+new Date()

  1. Date.now()
Date.now()

  1. new Date().valueOf()
new Date().valueOf()

17. 判断值是否为纯对象
function isPlainObject(obj) { if (typeof obj !== 'object' || obj === null) return falselet proto = obj while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto) }return Object.getPrototypeOf(obj) === proto }

    推荐阅读