收藏 | JS开发必须知道的41个技巧

【本文来自转载】Vue中文社区
转载来自—作者:火狼—腾讯云开发文章: 腾讯云开发文章

本博客转载源码地址: https://github.com/lanzhsh/react-vue-koa


2, Object

2-1, 对象变量属性
const flag = true;
const obj = { a: 0, [flag ? "c" : "d"]: 2  };
// obj => { a: 0, c: 2 }
2-2, 对象多余属性删除
const { name, age, ...obj } = { name: '张三', age: 13, dec: '描述1', info: '信息' }
console.log(name)  // 张三
console.log(age)  // 13
console.log(obj)  // {dec: '描述1', info: '信息' }
2-3, 对象----解构
  • 对象嵌套属性解构
const { info:{ dec} } = { name: '张三', age: 13, info:{dec: '描述1', info: '信息' }}
console.log(dec) // 描述1
  • 解构对象属性别名
const { name:newName } = { name: '张三', age: 13 }
console.log(newName)  // 张三
  • 解构对象属性默认值
const { dec='这是默认dec值' } = { name: '张三', age: 13 }
console.log(dec) //这是默认dec值
2-4, 拦截对象

defineProterty和proxy的对比:

  1. defineProterty是es5的标准,proxy是es6的标准;
  2. proxy可以监听到数组索引赋值,改变数组长度的变化;
  3. proxy是监听对象,不用深层遍历,defineProterty是监听属性;
  4. 利用defineProterty实现双向数据绑定(vue2.x采用的核心)



3, Number

3-1, 数字千分位
  • 方法一:
function thousandNum(num = 0) {
  const str = (+num).toString().split(".");
  const int = nums => nums.split("").reverse().reduceRight((t, v, i) => t + (i % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");
  const dec = nums => nums.split("").reduce((t, v, i) => t + ((i + 1) % 3 ? v : `${v},`), "").replace(/^,|,$/g, "");
  return str.length > 1 ? `${int(str[0])}.${dec(str[1])}` : int(str[0]);
}

thousandNum(1234); // "1,234"
thousandNum(1234.00); // "1,234"
thousandNum(0.1234); // "0.123,4"
console.log(thousandNum(1234.5678)); // "1,234.567,8"
  • 方法二
console.log('1234567890'.replace(/\B(?=(\d{3})+(?!\d))/g, ","))
console.log((1234567890).toLocaleString())
3-2, 字符串转数字
  • 方法一

用*1来转化为数字,实际上是调用.valueOf方法

'32' * 1            // 32
'ds' * 1            // NaN
null * 1            // 0
undefined * 1    // NaN
1  * { valueOf: ()=>'3' }        // 3
  • 方法二
+ '123'            // 123
+ 'ds'               // NaN
+ ''                    // 0
+ null              // 0
+ undefined    // NaN
+ { valueOf: ()=>'3' }    // 3
3-3, 判断小数是否相等

肯定有人会说这还不简单,直接用’==='比较;
实际上0.1+0.2 !==0.3,因为计算机不能精确表示0.1, 0.2这样的浮点数,所以相加就不是0.3了

Number.EPSILON=(function(){   //解决兼容性问题
    return Number.EPSILON?Number.EPSILON:Math.pow(2,-52);
})();
//上面是一个自调用函数,当JS文件刚加载到内存中,就会去判断并返回一个结果
function numbersequal(a,b){ 
    return Math.abs(a-b)<Number.EPSILON;
  }
//接下来再判断   
const a=0.1+0.2, b=0.3;
console.log(numbersequal(a,b)); //这里就为true了
3-3, 双位运算符

双位运算符比Math.floor(),Math.ceil()速度快

~~7.5                // 7
Math.ceil(7.5)       // 8
Math.floor(7.5)      // 7

~~-7.5         		 // -7
Math.floor(-7.5)     // -8
Math.ceil(-7.5)      // -7

所以负数时,双位运算符和Math.ceil结果一致,正数时和Math.floor结果一致

3-3, 取整和奇偶性判断
  • 判断奇偶数
const num=5;
!!(num & 1) // true
!!(num % 2) // true



2, Boolean

2-1, 判断数据类型
function dataTypeJudge(val, type) {
  const dataType = Object.prototype.toString.call(val)
  					.replace(/\[object (\w+)\]/, "$1").toLowerCase();
  return type ? dataType === type : dataType;
}
console.log(dataTypeJudge("young")); // "string"
console.log(dataTypeJudge(20190214)); // "number"
console.log(dataTypeJudge(true)); // "boolean"
console.log(dataTypeJudge([], "array")); // true
console.log(dataTypeJudge({}, "array")); // false

可判断类型:undefined、null、string、number、boolean、array、object、symbol、date、regexp、function、asyncfunction、arguments、set、map、weakset、weakmap

    // const dataType = Object.prototype.toString.call(val)
    //                     .replace(/\[object (\w+)\]/, "$1").toLowerCase();

    // const dataType = Object.prototype.toString.call(val);  //  [object String] 
    
    // const dataType = Object.prototype.toString(val);  // [object Object]

    // const dataType = Object.toString.call(val);    
    // 报错 -- TypeError: Function.prototype.toString requires that 'this' be a Function

    // const dataType = Object.toString();   // function Object() { [native code] }

==深入理解Object.prototype.toString.call(): ==
https://www.jianshu.com/p/e4237ebb1cf0

2-2, 使用Boolean过滤数组假值
const compact = arr => arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]) 
 //[ 1, 2, 3, 'a', 's', 34 ]
2-3,短路运算
  • == ||(或)==
const flag = false || true //true
// 某个值为假时可以给默认值
const arr = false || []    // []
  • == &&(与)==
const flag1 = false && true //false
const flag2 = true && true //true



1, Array

1-1, 数组交集
  • 普通数组
const arr1 = [1, 2, 3, 4, 5 , 8 ,9],arr2 = [5, 6, 7, 8, 9];
const intersection = arr1.filter(function (val) { return arr2.indexOf(val) > -1 })
console.log(intersection) //[5, 8, 9]
  • 数组对象

数组对象目前仅针对value值为简单的Number,String,Boolan数据类型
文中JSON.stringif比较对象是简写方法

const arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name5', id: 5 }];
const arr2 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
const result = arr2.filter(function (v) {
  return arr1.some(n => JSON.stringify(n) === JSON.stringify(v))
})
console.log(result); 
// [{ name: 'name1', id: 1 },{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name5', id: 5 }]
1-2, 数组并集
  • 普通数组
const arr1 = [1, 2, 3, 4, 5, 8, 9]
const arr2 = [5, 6, 7, 8, 9];
const result = arr1.concat(arr2.filter(v => !arr1.includes(v)))
console.log(result) //[1, 2, 3, 4, 5, 8, 9, 6, 7]
  • 数组对象
const arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];
const arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
let arr3 = arr1.concat(arr2);
let result = [];
let obj = [];
result = arr3.reduce(function (prev, cur, index, arr) {
  obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur);
  return prev;
}, []);
console.log(result); 
//[{ name: 'name1', id: 1 },{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name4', id: 4 },{ name: 'name5', id: 5 }]
1-3, 数组差集

数组arr1相对于arr2所没有的

  • 普通数组
const arr1 = [1, 2, 3, 4, 5, 8, 9]
const arr2 = [5, 6, 7, 8, 9];
const diff = arr1.filter(item => !new Set(arr2).has(item))
console.log(diff) //[ 1, 2, 3, 4 ]
  • 数组对象
let arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];
let arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
let result = arr1.filter(function (v) {
  return arr2.every(n => JSON.stringify(n) !== JSON.stringify(v))
})
console.log(result); 
// [ { name: 'name2', id: 2 }, { name: 'name3', id: 3 } ]
1-4, 数组补集

两个数组各自没有的集合

  • 普通数组
const arr1 = [1, 2, 3, 4, 5, 8, 9]
const arr2 = [5, 6, 7, 8, 9];
const difference = Array.from(
  new Set(arr1.concat(arr2)
  		  .filter(v => !new Set(arr1).has(v) || !new Set(arr2).has(v))
          )
) 
console.log(difference) //[ 1, 2, 3, 4, 6, 7 ]
  • 数组对象
let arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];
let arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
let arr3 = arr1.concat(arr2);
let result = arr3.filter(function (v) {
  return arr1.every(n => JSON.stringify(n) !== JSON.stringify(v))  || 
  		 arr2.every(n => JSON.stringify(n) !== JSON.stringify(v))
})
console.log(result); 
// [{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name4', id: 4 },{ name: 'name5', id: 5 }]

差集就是数组arr1相对于arr2所没有的集合,补集是两个数组各自没有的集合

1-5, 数组去重
  • 普通数组
console.log(Array.from(new Set([1, 2, 3, 3, 4, 4]))) //[1,2,3,4]
console.log([...new Set([1, 2, 3, 3, 4, 4])]) //[1,2,3,4]
  • 数组对象
const arr = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
 const result = [];
 arr.forEach(item=>{
    !result.some(v => JSON.stringify(v) === JSON.stringify(item)) 
    && result.push(item)
 })
 console.log(result) 
 //[{ name: 'name1', id: 1 },{ name: 'name2', id: 2 },{ name: 'name3', id: 3 },{ name: 'name4', id: 4 },{ name: 'name5', id: 5 }]
1-6, 数组排序

sort是浏览器内置方法;默认是升序排序,默认返回一个函数,有两个参数:
(a, b) => a - b 是升序;
(a, b) => b - a 是降序。

  • 普通数组
console.log([1, 2, 3, 4].sort((a, b) => a - b)); // [1, 2,3,4] 升序
console.log([1, 2, 3, 4].sort((a, b) => b - a)); // [4,3,2,1] 降序
  • 数组对象
const arr1 = [{ name: "Rom", age: 12 }, { name: "Bob", age: 22 }]
				.sort((a, b) => { return a.age - b.age })			//升序
const arr2 = [{ name: "Rom", age: 12 }, { name: "Bob", age: 22 }]
				.sort((a, b) => { return -a.age + b.age })			//降序
console.log(arr2) // [{ name: 'Bob', age:22 }, { name: 'Rom', age: 12 }]
console.log(arr1) // [ { name: 'Rom', age: 12 }, { name: 'Bob', age: 22 } ]
1-7, 数组最大值
  • 普通数组
Math.max(...[1, 2, 3, 4]) //4
Math.max.apply(this, [1, 2, 3, 4]) //4
[1, 2, 3, 4].reduce((prev, cur, curIndex, arr) => {
   return Math.max(prev, cur);
}, 0) //4
  • 数组对象

取数组对象中id的最大值

const arr = [{ id: 1, name: 'jack' },{ id: 2, name: 'may' },{ id: 3, name: 'shawn' },{ id: 4, name: 'tony' }]
const arr1 = Math.max.apply(Math, arr.map(item => { return item.id }))
const arr2 = arr.sort((a, b) => { return b.id - a.id })[0].id
console.log(arr1) // 4
console.log(arr2) // 4
1-8, 数组求和
  • 普通数组
[1, 2, 3, 4].reduce(function (prev, cur) {
  return prev + cur;
}, 0) //10
  • 数组对象
const sum = [{age:1},{age:2}].reduce(function (prev, cur) {
  return prev + cur.age;
}, 0) //3
console.log(sum)
1-9, 数组合并
  • 普通数组
const arr1 =[1, 2, 3, 4].concat([5, 6]) 	//[1,2,3,4,5,6]
const arr2 =[...[1, 2, 3, 4],...[4, 5]] 	//[1,2,3,4,5,6]
const arrA = [1, 2], arrB = [3, 4]
const arr3 =[].concat.apply(arrA, arrB)		//arrA值为[1,2,3,4]
  • 数组对象
const arr4 = [{ age: 1 }].concat([{ age: 2 }])
const arr5 = [...[{ age: 1 }],...[{ age: 2 }]]
console.log(arr4) 		//[ { age: 1 }, { age: 2 } ]
console.log(arr5) 		// [ { age: 1 }, { age: 2 } ]
1-10, 数组是否包含值
  • 普通数组
console.log([1, 2, 3].includes(4)) //false
console.log([1, 2, 3].indexOf(4)) //-1 如果存在换回索引
console.log([1, 2, 3].find((item) => item === 3)) //3 如果数组中无值返回undefined
console.log([1, 2, 3].findIndex((item) => item === 3)) //2 如果数组中无值返回-1
  • 数组对象
const flag = [{age:1},{age:2}].some(
		v=>JSON.stringify(v)===JSON.stringify({age:2})
	)
console.log(flag)
1-11, 数组每一项都满足 && 数组有一项满足

数组每一项都满足

  • 普通数组
[1, 2, 3].every(item => { return item > 2 })
  • 数组对象
const arr = [{ age: 3 }, { age: 4 }, { age: 5 }]
arr.every(item => { return item.age > 2 }) // true

数组有一项满足

  • 普通数组
[1, 2, 3].some(item => { return item > 2 })
  • 数组对象
const arr = [{ age: 3 }, { age: 4 }, { age: 5 }]
arr.some(item => { return item.age < 4 }) // true
1-12, 对象转数组, 数组转对象
  • 将数组的key和value转化成数组
Object.keys({ name: '张三', age: 14 }) //['name','age']
Object.values({ name: '张三', age: 14 }) //['张三',14]
Object.entries({ name: '张三', age: 14 }) //[[name,'张三'],[age,14]]
Object.fromEntries([name, '张三'], [age, 14]) 
//ES10的api,Chrome不支持 , firebox输出{name:'张三',age:14}
  • 将数组的值转化为对象的value
const arrName = ['张三', '李四', '王五']
const arrAge=['20','30','40']
const arrDec = ['描述1', '描述2', '描述3']
const obj = arrName.map((item,index)=>{
  return { name: item, age: arrAge[index],dec:arrDec[index]}
})
console.log(obj) // [{ name: '张三', age: '20', dec: '描述1' },{ name: '李四', age: '30', dec: '描述2' },{ name: '王五', age: '40', dec: '描述3' }]
1-13, 数组解构
const arr=[1,2]; //后面一定要加分号,因为不加解释器会认为在读数组
[arr[1], arr[0]] = [arr[0], arr[1]]; // [2,1]

1, Array

1, Array

1, Array

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值