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]

以上方法只适用于二维数组,如果是二维以上数组,通过递归实现

 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 false

  let proto = obj
  while (Object.getPrototypeOf(proto) !== null) {
    proto = Object.getPrototypeOf(proto)
  }

  return Object.getPrototypeOf(obj) === proto
}

你可能感兴趣的:(js中的小技巧)