Array.sort()
数组的默认排序是 按照字典排序 的,即使用字符串比较(原因想想也知道)
所以就可能出现以下情况:
1
2
3
4
| [9,80,3,10,5,6].sort()
// [ 10, 3, 5, 6, 80, 9 ]
// Oops!
|
教训:一定一定要在使用数组排序方法传入比较函数啊
1
2
3
4
5
| [9,80,3,10,5,6].sort(function(a, b) {
return a - b;
});
// [ 3, 5, 6, 9, 10, 80 ]
|
Date
Date
的getXXX系列也是最让人混乱的一个地方:
getFullYear() -> 这才是常用的4位数字表示年份
getMonth() -> 返回值是0-11,表示1月到12月
getDate() -> 返回值是1-31,表示1日到31日(视月份而定)
getDay() -> 返回值是一周的某一天不是一个月的某一天
getHours() -> 返回值是0-23
getMinutes() -> 返回值是0-59
getSeconds() -> 返回值是0-59
想让数字以双位数显示可以用下面的函数
1
2
3
| function addZero(n) {
return (n < 10 ? '0' : '') + n;
}
|
Add (operator +)
由于字符串拼接的存在,+
号几乎把所有的东西优先转换成字符串类型。同时+
号又作为加号存在,于是就出现了以下噩梦般的场景
减号、乘除号则是优先转换成数字
undefined
转换为数字是NaN
, null
转换为数字是0
1
2
3
4
5
| 1 + '2'
// -> '12'
1 - '2'
// -> -1
|
parseInt
parseInt(string, radix);
ECMAScript3会把0X
识别为8进制,于是在省略第二个参数radix
的情况下,就会出现以下情况
1
2
3
4
5
6
7
8
| parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
|
虽然ES5已经修复了这个问题,但是最好还是继续使用解决方案(或者避免使用parseInt
)。
解决方案:
1
2
3
4
5
| parseInt('08', 10); // 8
+'08'; // 8
~~'08'; // 8
new Number('08'); // 8
Math.ceil('08'); // 8
|
参考链接
this
以前提到过的 函数调用时,this会指向全局对象 问题:
在对象里调用函数(不是方法),this也会指向全局对象
使用ES6的=>
已经不在有这个问题了
最简单的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| var bob = {
name: 'bob',
friends: ['john', 'foo', 'bva'],
printFriends: function() {
this.friends.forEach(function(friendName) {
console.log(this.name + ' knows ' + friendName);
});
}
};
bob.printFriends();
// output:
//
// undefined knows john
// undefined knows foo
// undefined knows bva
|
伪块级作用域
JavaScript使用的是函数作用域(Function Scope),但是它又用了类C语法的花括号,让很多人误以为是块级作用域(Block Scope),导致了很多理解上的问题
1
2
3
4
5
6
7
| var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
|
不过在ES6已经有let
来实现块级作用域了