console.log(parseInt('60', 40))的结果是什么? // NaN
console.log(parseInt('11', 20))的结果是什么? // 21
分析:
- parseInt(string,radix)
函数可解析一个字符串,并返回一个整数。
- 如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
- 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
- 如果 string 以 1 ~ 9
的数字开头,parseInt() 将把它解析为十进制的整数
- radix表示要解析的数字的基数。该值介于2 ~ 36
之间。
- 如果省略该参数或其值为 0,则数字将以 10 为基础来解析。
- 如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
- 如果该参数小于 2 或者大于 36
,则 parseInt() 将返回NaN
。
console.log(123 + '456'); // 123456
console.log(123 + 'a' + 1); // 123a1
console.log(123 + 1 + 'a'); // 124a
console.log(typeof(123 + 'a')) // String
console.log('a' - 1); // NaN
console.log(typeof('a' - 1)) // number
console.log(1-'a'); // NaN
console.log(typeof(1-'a')) // number
分析:
- 在JavaScript中,+(加号)
运算符的规则,只有两种;数字和数字相加,字符串和字符串相加;
- 加法运算符,会触发三种类型的转换: 转换为原始值,转换为数字,转换为字符串
- 字符串连接,任何与字符串连接的类型都变味字符串类型
- -(减号)
运算符作为 number
类型运算; 如果字符串类型与数字相减,它默认会把改字符串转化为 number
类型再进行运算,如果字符串有字母,那么转化后与数字无法运算,它的结果会是 NaN(不是一个数)
,不过他的类型仍然为 number
var a = 2, b = 3;
var c = a+++b; // 5
console.log(c)
分析:从左到右
按序执行,先执行 a++
,再执行+b
;
为什么0.1+0.2 > 0.3, 0.2+0.3=0.5??
console.log(0.1+0.2) //0.30000000000000004
console.log(0.2+0.3) // 0.5
console.log(0.1) // 0.1
分析:
- 二进制浮点数表示法并不能精确的表示类似
0.1
这样的简单数字,会有舍入误差。
浮点数是使用64位固定长度
来表示的,1位
表示符号位
,11位
表示指数位
,剩下的52位
是尾数位
。0.1+0.2
相加,操作数会先被转成二进制,然后再计算:0.1=0.0001 1001 1001… ,0.2=0.0011 0011 0011… ; 双精度浮点数的小数最多支持52
位,所以 0.1 + 0.2得到的是一串新的二进制数,因为浮点小数位的限制,所以会截断二进制数;然后将其转换为十进制数就变成了0.30000000000000004 0.2
和0.3
转换为二进制
后,内存里,他们的尾数位
都是等于52位
的,相加后必定大于52位
;并且相加后前52位尾数
都是0
,截取后恰好是0.1000000000000000000000000000000000000000000000000000
也就是0.5
- 既然
0.1
不是0.1
了,为什么在console.log(0.1)
的时候还是0.1
呢?这是因为,在console.log
的时候会将二进制
转换为十进制
,十进制
在会转为字符串
的形式,在转的过程中发生了取近似值
,所以打印出来就是一个近似值
的字符串
。
console.log(1);
setTimeout (function(){
console.log(2);
},500);
setTimeout (function(){
console.log(3);
},0);
setTimeout (function(){
console.log(4);
},1000);
console.log(5);
// 打印输出: 15324
分析:页面中的定时器操作都会按序
放入队列
中,等函数调用栈
都执行完毕以后(所有可执行的代码执行完毕以后),才会按序,根据定时器的时间长短执行队列中的代码;
var User = {
nickName: 'lisa',
getName: function() {
return this.nickName;
}
};
console.log(User.getName()); // lisa
var fun = User.getName;
console.log(fun()); // undefined
分析:fun
是在 window
的上下文中被执行的,所以不会访问到 nickName
这个属性,因此返回 undefined
for(var i = 0; i <= 3; i++) {
setTimeout(function() {
console.log(i); // 4 4 4 4
},0)
}
for(let i = 0; i <= 3; i++) {
setTimeout(function() {
console.log(i); // 0 1 2 3
},0)
}
分析:
4. 使用 var
定义变量,因为作用域的原因,在这里它相当于全局变量
;在for循环结束后,值会被覆盖掉
,初始值为0,循环结束时为4,所以被覆盖掉后输出的就是4;setTimeout
是一个异步
,他拿到的是循环结束后的值;所以会直接输出4个4
5. let
有自己的 作用域
,因此在for循环当中,相当于在代码块里使用let
;每次循环后都会重新声明
并初始化
一次。也就是在每次循环后,它的值都会单独保存
在一个独立的作用域
中,不会被覆盖掉
。因此输出时输出0123