typeof
typeof判断是否为对象时重点关注null。
(1)在对变量执行typeof的时候,得到的结果并不是该变量的类型,而是该变量持有的值得类型;
(2)typeof运算符总是返回一个字符串
(3)typeof运算符检测null时为'object'
console.log(typeof typeof 42); // string
typeof 42返回的是字符串类型的"number",再typeof "number",返回的是”string“
conosle.log(typeof null) //'object'
//检查一个变量是否是对象之前,首先判断该变量是否为null
let obj ={}
if(obj !== null && typeof obj === 'object'){
// do something
}
数值的注意点
注意数值的大小
JS最大可存储的安全整数(9007199254740991,16位整数),最小可存储的安全整数(-9007199254740991)
数值计算时注意js数值类型的精度
console.log(0.1+0.2 === 0.3) //false
由于计算的精度问题,比较小数相等时最好不用===进行比较,可以通过一下方式比较
console.log(Math.abs(0.1+0.2 - 0.3) < 1e-10) // true
NaN
(1)NaN不等于包括自身在内的任何值,可以利用这个特性判断一个变量是否为NaN,如果一个变量它不等于自身,那么这个变量就为NaN。
(2)使用isNaN判读一个变量是否为NaN(尽量不使用)。
原因:isNaN()方法首先会将要判断的变量转换为数值类型
(3)使用Number.isNaN()判读一个变量是否为NaN,与isNaN()方法的区别:
Number.isNaN()首先会判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换
console.log(NaN == NaN); //false
console.log(NaN === NaN); //false
//如果一个变量它不等于自身,那么这个变量就为NaN。
let a = NaN;
console.log(a === a); // false
console.log(isNaN('abc')); // true 首先将'abc'转换为数值类型时为NaN,因此最终结果为true
console.log(isNaN('123')); // false
console.log(isNaN([])); // false 首先将[]转换为数值类型时为0,因此最终结果为false
console.log(isNaN({})); // true 首先将{}转换为数值类型时为NaN,因此最终结果为true
console.log(isNaN(NaN)); //true
//Number.isNaN()首先会判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换
console.log(Number.isNaN('12k')) // false
console.log(isNaN('12k')) // true
console.log(Object.is(NaN, NaN)); //true
正确使用parseInt()
parseInt()共有两个参数,第一个参数表示待转换的字符串(如果不是字符串,首先会将其转换为字符串);第二个字符串表示需要转换的进制数。
使用parseInt()的注意点:
(1)parseInt()最好加上第二个参数(要转换的进制数)。如果不传第二个参数,那么转换的值由第一个参数决定(如Ox开头的字符串为16进制,0开头的有的是8进制,有的是十进制,有歧义)
(2)不要使用parseInt()给小数取整
console.log(parseInt('0xfff')); //4095 16进制
console.log(parseInt('0666')); //666 十进制
console.log(parseInt('0666', 8)); //438 八进制
//不要使用parseInt()给小数取整
console.log(parseInt(0.000000000006)); //6 ???
首先parseInt()对于带转换的值不是字符串的会将其转换为字符串
String(0.000000000006) // '6e-12'
parseInt('6e-12') // 6
慎用||填充默认值
注意:undefined,null,0,''(空字符串),NaN进行Boolean转换时会被转换为false
let obj = {
name: 'Bruce',
id: 0,
num: undefined,
a: null,
b: ''
};
obj.id = obj.id || 11;
obj.num = obj.num || 22;
obj.a = obj.a || 'a';
obj.b = obj.b || 'b';
console.log(obj); //{name: 'Bruce', id: 11, num: 22, a: 'a', b: 'b'}
上面代码中id,num,a,b都使用了默认值,
而||的语法转换规则为:expr1 || expr2 <=> Boolean(expr1) ? expr1 : expr2
只有Boolean(expr1) 被转换为true才会返回expr1,否则返回expr2。
而undefined,null,0,''(空字符串),NaN将被转换为false,因此它们都使用了默认值
Boolean(undefined) // false
Boolean(null) // false
Boolean(false) // false
Boolean(0) // false
Boolean(NaN) // false
数组的的使用注意
includes()和indexOf()
includes()方法返回布尔值,indexOf()返回数组子项的索引。
indexOf()在需要索引的情况下使用。
如果仅需要知道某个元素是否存在于数组中,使用includes()方法。
includes()方法能找到NaN,返回true;indexOf()找不到NaN,返回-1。
[NaN].includes(NaN) // true
[NaN].indexOf(NaN) // -1
find()和some()
Array.find()方法需要一个回调函数作为参数,并返回第一个符合条件的值。
Array.some()方法同样需要一个回调函数作为参数,但它返回的是一个布尔值,只要数组中有元素符合条件就会返回true,否则返回false。
当我们需要知道数组中是否存在某个元素时,使用some()方法更佳,因为some()方法直接返回一个布尔值。
另外,如果符合条件的返回值为0,使用some比find更合适。
let arr = [0, 1, 2, 3];
let result = arr.find((item) => item === 0);
let result1 = arr.some((item) => item === 0);
console.log(result, result1); // 0 true
if (result) {
console.log('存在');
} else {
console.log('不存在');
}
//返回的是不存在,因为find符合条件返回的值是0,此时if条件判断为false
补充:includes()方法和some()方法异同点
相同点:两者都返回一个布尔值,表示某项是否存在于数组中。
不同点:some()方法的参数是一个回调函数,includes()方法的参数是一个值。
JSON.stringify深拷贝注意点
const obj1 = {
name: undefined,
age: null,
fun: () => {
console.log('fun');
},
date: new Date(),
arr: [1, 2, 3, { a: 'aa' }],
num: NaN,
infinityMax: Infinity,
infinityMin: -Infinity
};
const cloneObj1 = JSON.parse(JSON.stringify(obj1));
console.log('obj1', obj1);
console.log('cloneObj1', cloneObj1);
1、当对象中有时间类型的时候,时间类型会被转为字符串类型数据
上面代码中obj代码经过深拷贝后data属性成为字符串表示"2022-08-04T08:25:19.733Z" ,不能调用getTime(),getYearFull()等方法。
上面代码中,当调用getTime()方法时 cloneObj1.data.getTime()会报错。
console.log(obj1.date.getTime());
console.log(cloneObj1.data.getTime());
2、当对象中有undefined或function类型的数据时,undefined和function会直接丢失
上面代码中name属性和fun属性都丢失了,另外,如果undefined,函数,symbol出现在数组的属性中,它们会被自动转换成null,如果它们单独出现会被转换为undefined。
3、当对象中有NaN,Infinity,-Infinity这三种值时,会变为null
4、当对象循环引用时,会报错