整理一些自己觉得有用的js的技巧跟知识点,嘛,想到哪写到哪吧,毕竟我记性这么差,还这么懒。
变量交换值
1 | var a = 'world', b = 'hello'; |
ES6的解构赋值算是我非常喜欢的一个功能了,允许按照一定模式,从数组和对象中提取值,对变量进行赋值。
如果是两个数字交换值的话,还可以这么做:1
2
3
4
5var a = 12, b = 2;
a ^= b;
b ^= a;
a ^= b;
console.log(a, b) // 2 12
这个东西就比较黑科技了,按位运算符异或^
,将数字转为二进制进行按位比对,上面的计算步骤大概是(位数就不写全了):1
2
3a = 12 ^ 2 = 1100 ^ 0010 = 1110 = 14;
b = 14 ^ 2 = 1110 ^ 0010 = 1100 = 12;
a = 14 ^ 12 = 1110 ^ 1100 = 0010 = 2;
快速取整
1 | console.log(~~47.11) // 47 |
按位取反运算符~
,会先判断类型进行隐式转换,之后将数字原码转二进制之后进行取反,再取其补码,除符号位外取反再加1
对于数字和字符串类型,执行两次后就可以快速实现一个取整的效果,其他类型会转换成0
转换数字
1 | console.log(+'1') // 1 |
当进行运算时会隐式转换数字,所以使用+
可以快速地转换数字
转换Boolean
1 | console.log(!!1) // true |
二次取反不解释,简单粗暴
参数解构和字符串拼接
1 | let person = { |
在函数方法中使用参数解构可以更方便的获取数组/对象中的值。
在拼接字符串时,在替换引号之后,可以使用${}
将变量直接写入字符串中,相比于+
拼接字符串更加灵活。
valueOf 和 toString
抛开二者的基本作用不谈,作为对象和方法的隐式属性,有一些意想不到的效果1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var a = {
value: 0,
valueOf: function () {
console.log('valueOf');
return this.value += 1;
},
toString: function () {
console.log('toString');
return this.value += 1;
}
}
alert(a); // valueOf 1
alert(a); // valueOf 2
console.log(+a); // toString 3
console.log(+a); // toString 4
可以发现,运算会触发对象的valueOf
方法,取值会触发toString
方法
以上的写法,每次对于对象获取到的值都不同,在调用之后都会发生改变,于是就可以实现一个很有意思的效果。1
console.log(a === 1 && a === 2 && a === 3); // valueOf valueOf valueOf true
&&
运算符也会触发valueOf
,就能实现这么一个一眼看上去几乎不可能为true的表达式。1
2
3
4
5
6
7
8
9
10
11
12
13function add (num) {
var sum = num;
var _add = function (_num) {
sum += _num;
return _add;
}
_add.toString = function () {
return sum;
}
return _add;
}
console.log(add(1)(2)(3)) // 6
既然取值触发toString
,那么就可以在这上面做一些文章了,将一个函数方法链式调用来计算所有参数和,最后在取值的时候使用toString
方法拿到值。
Spread 扩展运算符
ES6的扩展运算符...
可以将一个数组转为用逗号分隔的参数序列1
2
3
4
5
6function add(x, y) {
return x + y;
}
let numbers = [4, 38];
add(...numbers) // 42
合并数组1
2
3let arr1 = ['a', 'b'];
let arr2 = ['c'];
console.log([...arr1, ...arr2]); // ['a', 'b', 'c']
数组&对象克隆,拒绝浅拷贝1
2
3
4
5let arr = [], obj = {};
// let newArr = Object.assign([], arr);
// let newArr = JSON.parse(JSON.stringify(arr));
let newArr = [...arr];
let newObj = {...obj};
取数组最大值/最小值1
2
3let arr = [4, 6, 55, 12, 21];
console.log(Math.max(...arr)); // 55
console.log(Math.min(...arr)); // 4
将字符串转为数组1
console.log([...'hello']) // ['h', 'e', 'l', 'l', 'o']
平铺多维数组,这里只列举二维的1
2
3let arr11 = [11, [22, 33], [44, 55], 66];
let flatArr = [].concat(...arr);
console.log(flatArr); // [11, 22, 33, 44, 55, 66]
Set 数组去重
1 | let unique = arr => [...new Set(arr)]; |
ES6 提供了新的数据结构 Set。它类似于数组,允许存储任何类型的唯一值。
Set 本身是一个构造函数,用来生成 Set 数据结构,使用 Set 将数组处理之后再将其转为数组,就可以实现简单的数组去重
生成随机字符串
1 | Math.random().toString(32).substr(2) |
生成结果类似于’n76ebcr9sg’这样的字符串,toString
方法可以转换数字进制,32进制数字包含了a-z和0-9这些字符,在生成随机数转换32位后截取前两位的’0.’,就可以快速的生成一个随机字符串。
typeof
1 | typeof null // object |
在使用typeof判断数据类型的时候,需要注意null的类型判断也是’object’(毕竟万物皆对象)
由于js的基本类型没有数组类型,所以数组的typeof也是’object’,那么如何去区分数组和对象呢1
2
3
4
5
6
7
8
9let arr = [], obj = {}
Array.isArray(arr) // true
Array.isArray(obj) // false
typeof arr === 'object' && !isNaN(arr.length)//true
typeof obj === 'object' && !isNaN(obj.length)//false
Object.prototype.toString.call(arr) // [object Array]
Object.prototype.toString.call(obj) // [object Object]
instanceof
1 | new Number(1) instanceof Number // true |
在使用instanceof判断类型的时候也需要注意,instanceof只对对象实例生效,对于基本类型的验证都是false,而对于数组的类型判断,既是数组也是对象
在条件中使用 && 及 || 进行短语判断
1 | let foo = 10; |
这种写法算是利用了&&
和||
的特性,起到了和if语句相同的效果。&&
会执行所有的条件判断语句,||
执行到true的时候就会短路掉之后的条件,不去执行。
变量属性名
1 | let key = 'hello', value = 'world'; |
ES6允许使用变量来作为对象的属性。
浮点数计算
1 | console.log(0.1 + 0.2) // 0.30000000000000004 |
js的浮点数计算算是很烦人的一点了,转换二进制之后对于浮点数的识别很不友好,最简单的解决办法就是使用toFixed
了,还有就是转换为整数之后再进行计算,当然还有其它的方法,封装好的工具包等,就不多介绍了。
获取出现次数
当我们想要获取字符串中某个字符串出现的次数,比如ggasddghasdw
中’a’出现的次数1
2let str = 'ggasddghasdw';
console.log(str.split('a').length - 1) // 2
同理,对于数组元素也可以使用这样的方式1
2let arr = [1, 2, 3, 5, 3];
console.log(arr.toString().split(3).length - 1) // 2
深拷贝对象
使用ES6
的方法可以更灵活的完成对象的深拷贝1
2
3
4
5
6
7
8
9// bad
const original = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 });
delete copy.a; // copy => { b: 2, c: 3 }
// good
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 };
const { a, ...result } = copy; // result => { b: 2, c: 3 }
未完待续