本系列将会写一些在正常工作中会遇到的一些坑,然后分析它们的产生原因及解决办法.本文的内容主要来自<you don’t know JS>及日常工作的问题的一些总结.
坑一: 关于parseInt()方法转换字符串的问题,神坑!
1 | console.log(parseInt(1/0, 19)); //18 |
坑二: 位运算符~的妙用:
在许多编程语言中,查找值或函数执行过程中,大于等于0的值表示查找或执行成功,返回-1则表示查找或执行失败.因此当失败时,可以直接使用位运算符~进行判定,当为-1时, -(-1 + 1) 即为零,因此就可以直接进行布尔运算了.
1 | var a = "hello world"; |
位运算的另一个巧妙用法:将值截除为一个32位整数
1 | console.log(Math.floor(-.1)) //-1 |
坑三: 对于稀疏数组的输出差异
在谷歌浏览器中,对于长度为三,无内容的稀疏数组显示为undefined*3,对于长度为三,但内容都赋值为undefined的数组,显示为[undefined, undefined, undefined].但是此情况在IE浏览器中显示的内容都是两个等号!不过在火狐中相对比较正常,输出的是文字”三个空的数组”和[undefined, undefined, undefined]
坑四: JSON.stringify的妙用:
在序列化为JSON对象时,将该对象选择性输出,以得到想要的值;
1 | var a = { |
当然,这个时候stringify还可以传递一个函数进去进行判断.
1 | var a = { |
JSON.stringify()还有一个参数space,用来指定输出的缩进格式,space为数值时表示缩进的字符数,还可以是字符串,为字符串时最前面的十个字符用于每一级的缩进:
1 | var a = { |
从上面来看,使用位运算得到的值和Math.floor() 的值不尽相同,使用位运算相当于直接去掉了数字的小数点.
坑五: 当在函数内部为变量指定新值后,并不影响传参的值.
当函数内部制定了变量值后,输出的值是不一样的,我们来看一下例子:
1 | function foo(x) { |
其实主要的原因是这样的,当我们的a作为参数传到foo函数中的时候,foo中的参数x其实是获得了一个到a数组的指针,当x进行相应的数值处理操作的时候,会直接作用到a上面,但是当x的指针改变了,也就是x被重新赋值的时候,x的指针就指向新的[4,5,6]数组了,这个时候其实后面的push(7)的操作已经是对于新的数组,并没有对a数组进行相应的操作,故最后返回的a的值只是[1,2,3,4]
坑六: 为变量赋予常量值的问题
一个很小的问题(其实涉及到的知识点和上面是类似的),当我为一个变量赋予了一个常量值,但通过函数对这个常量值进行更改,那么更改会不会体现到这个常量值中呢?1
2
3
4
5
6
7function foo(x) {
x = x + 1;
console.log(x);
}
var a = 2;
foo(a);
console.log(a); //此时a还是为2
坑七: 关于浅复制的一些小技巧(也是对上面问题的另一种出理方案)
使用slice()方法对变量进行浅复制,达到不影响变量原来的值的目的.
1 | foo(slice() ) |
坑八: new出的对象
使用new方法new出来的变量都是属于对象,因此进行类型检测时都会显示为object型.
坑九: 关于隐式类型转换
对new出来的对象来讲,对其进行判断会有一个自动的隐式类型转换过程,自动调用数组中的valueof()方法,因此就有了以下这样的奇葩现象:
1 | var a = 2; |
其实这个问题很好解释,每次对b进行判断都是会调用其valueof方法,而valueof方法中a会自增1,因此会有b又等于2,又等于3的情况.