在Node.js中,除了SSR/爬虫之外,我们很少会操作DOM、BOM,而是直面服务器,更多的是偏向内存方面(文件操作,网络I/O等),所以编写安全可靠的JS代码非常重要,因此,需要掌握扎实的JS基础,甚至一些JS的奇淫技巧。(我个人非常推荐使用TypeScript,Type + ES.next,如果在编译期间甚至代码编写时就能发现一些错误,这将大大提高代码的可靠性)。下面是本小节的目录(然而简书的Markdown编辑器并不支持页内的目录跳转...)
类型判断
JS中目前有7种数据类型,其中undefined、null、string、number、boolean、symbol是六种基本类型,object是复杂(引用)类型。一般情况下使用typeof判断值的类型,使用instanceof判断某个对象是否是某构造函数的实例。
但是有一些bug:
typeof null //object
let fn = function(){};
typeof fn //function
在判断两个值是否相等时,==只要求值相等,当类型不同时会自动进行类型转换;===为严格相等,要求类型和值都相同才为true.
undefined==false //true
null==false //true
0==false //true
NaN==false //true
''==false //true
上面的五种情况都为true,这是JS中所有自动转换为boolean类型后值为false的情况,其它情况皆转换为true。
undefined==null //true
NaN==NaN //false
上面是两个特例,当不同类型的值使用==比较时,隐式转换规则如下(按下列优先级):
① 如果任一值是undefined或null,它们互相相等,但与其它的值都不相等
undefined==null //true
undefined==false //false
undefined==0 //false
② 如果任一值是数字类型,则将与之比较的值转换为数字
1==false //false
2==true //false
0==[] //true , 由Number([])可得结果为0
1==[1] //true
12==[1,2] //false 右侧转换为数字为NaN
1=='1' //true
1=='1a' //false 右侧转换为数字为NaN
③ 如果任一值是boolean类型,则将与之比较的值转换为boolean类型,这里有些特殊情况*
[]==false //true
{}==false //false
Boolean([]) //true
Boolean({}) //true
/*此处应该将第一行理解为[]转换为数字0,false也转换为数字0,所以值相等*/
!{}==false //true
![]==false //true
/*!优先级比==高,先将[]转换为布尔值true,所以![]的值为false*/
![]==[] //true
④ 除去上面四种数据类型,只剩下string、object、symbol三种数据类型了,其中symbol类型的值有些特殊,除了自身以外,不与任何值相等,虽然它使用Boolean()转换为布尔值为true,但它与true并不相等
const s=Symbol('s')
const y=Symbol('s')
s==s //true
s==y //false
Boolean(s) //true
s==true //false
当字符串与对象比较时,对象会转换成字符串,再进行比较
'1'==[1] //true
当对象与对象比较时,除非是相同的引用,否则为false。
const a={},b={}
a==b //false
a=={} //false
b=={} //false
const c=a;
c==a //true
因此,除去symbol,undefined,null以后,number类型的优先级最高,也可以理解为隐式类型的转换最后都是数值的比较。但是在实际代码编写中,极不推荐使用==,哪怕你和我一样也对这些转换规则铭记于心 ☋ ☋ ☋ ,总之最好是全部使用===来判断两个值是否相等,不过在使用===时也有两个特殊情况:
NaN===NaN //false
+0===-0 //true
现在ES6中提供了一个新的方法Object.is(value1,value2)用来判断两个值是否相同,修复了===的两个bug
Object.is(NaN,NaN) //true
Object.is(+0,-0) //false
补充:对于引用类型的深拷贝,可以使用JSON.parse和JSON.stringify,如数组:
let obj={name:'ht'};
let arr1=[1,2,obj],arr2;
arr2=JSON.parse(JSON.stringify(arr1))
arr2[2].name='wt';
console.log(arr1) //[1,2,{name:'ht'}
console.log(arr2) //[1,2,{name:'wt'}
作用域
引用传递
- js中什么类型是引用传递,什么类型是值传递?如何将值类型的变量以引用的方式传递?
答:简单点说,对象是引用传递,基础类型是值传递,通过将基础类型包装可以以引用的方式传递。其实严格来说JS中没有引用传递,只是传递引用。
网友评论