类型
typeof 判断类型,返回的是类型的字符串值
特殊:1
2
3
4
5typeof null === 'object'
typeof function a() {} === 'function'
var a
typeof a // 'undefined'
typeof b // 'undefined' // 即使b未声明,也会返回undefined
函数是对象的一个子集,也有属性,比方说a.length,是声明的参数个数。
变量没有类型,但他们的值持有类型。
值
如果字符串键值能被强制类型转换为十进制数字的话,它就会被当做数字索引来处理。1
2
3var a = [];
a['13'] = 42;
a,length; //14
字符串是类数组,具有 length 属性以及 indexof() 和 concat() 方法。
字符串是不可变的,也就是字符串的成员函数不会改变其原始值,数组是可变的。有的操作可以先”借用”数组的方法。
undefined 只有一个值,即 undefined,null 类型也只有一个值,即 Null。它们的名称既是类型也是值。1
2null:指空值;曾经赋过值,但目前没有值;是一个特殊的关键字,不是标识符
undefined:指没有值,从未赋值;是一个标识符,可以被当做变量来使用和赋值
NaN 指”不是一个数字”,理解为”无效数值”、”失败数值”、”坏数值”。他和自身不相等,是唯一一个非自反的值,即 NaN != NaN 为true。
怎么判断一个值是 NaN 呢? ES6 有工具函数Number.isNaN()
可以判断。
原生函数
所有 typeof 返回值为”object” 的对象都包含一个内部属性[[Class]],这个属性无法直接访问。一般通过Object.prototype.toString(...)
来查看。
基本类型是没有.length 和 .toString() 这样的属性和方法,需要通过封装类型才能访问,此时 Javascript 会自动为基本类型值包装一个封装对象。1
2
3
4var a = new Boolean(false);
if(!a) {
console.log('Oops'); // 执行不到这里
}
获取一个封装对象中的基本类型值,可以使用 valueOf() 函数。
强制类型转换
抽象值操作
- ToString
负责处理非字符串到字符串的强制类型转换
基本类型规则:null 转换为 “null”,undefined 转换为 “undefined”,true 转换为 “true”。
普通对象来说,除非自定义,否则 toString() 会返回内部属性[[Class]]的值,如”[[object Object]]”。
数组的 toString() 经过了重新定义,将所有单元字符串化后再用”,”进行连接。 - ToNumber
true 转换为1,false 转换为0,null 转换为0,undefined 转换为NaN。
对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,再通过规则将其转换为数字。
将值转换为基本数据类型,ES规范会检查是否有 valueOf() 方法,如果有并且返回基本类型值,则使用该值进行强制类型转换,如果没有就使用toString()的返回值进行强制类型转换。 - ToBoolean
以下这些是假值:undefined、null、false、+0、-0 和 NaN、””。假值类型的布尔强制类型转换结果为 false。
假值对象:他们都是封装了假值类型的对象。1
2
3var a = new Boolean(false); // true
var b = new Number(0); // true
var c = new String(""); // true
显式强制类型转换
- 字符串和数字的显示转换
字符串和数字之间的转换是通过 String(…) 和 Number(…) 这两个内建函数(原生构造函数)来实现的,请注意它们前面没有 new 关键字,并不创建封装对象。
日期转换为数字
隐式强制类型转换
字符串和数字的隐士强制类型转换
- 运算符能用于数字加法,也能用于字符串拼接,那么怎么判断执行哪个操作呢?
1
2
3
4
5
6
7
81 + '1' // 11
1 + true // 2
1 + false // 1
1 + undefined // NaN
'a' + true // atrue
var a = [1, 2]
var b = [3, 4]
a+b // "1,23,4"
如果 + 的其中一个操作数是字符串(或者通过以下步骤可以得到字符串)则执行字符串拼接,否则执行数字加法。
步骤:如果其中一个操作数是对象(包括数组),对其首先进行 ToPrimitive 抽象操作,该抽象操作再调用[[DefaultValue]],以数字作为上下文。- 运算符能用于数字加法,也能用于字符串拼接,那么怎么判断执行哪个操作呢?
布尔值和数字的隐士强制类型转换
宽松相等和严格相等
常见误区是:“==检查值是否相等,===检查值和类型是否相等”。
正确解释是:“==允许在相等比较中进行强制类型转换,而===不允许”。
- 字符串和数字之间的相等比较
x == y:x 是数字,y 是字符串,则将 字符串y 转换为数字(ToNumber(y))进行判断。 - 其他类型和布尔值的相等比较
x == y: x 是布尔值,则将布尔值 x 转换为数字(ToNumber(x))进行判断。1
2
3var x = true;
var y = "42";
x == y // false
首先将 x 转换为数字1,则接下来进行 1 == “42”的比较,”42”转换为数字42,最后变成 1== 42,则为 false。
建议:无论什么情况下都不要使用 == true 和 == false
- null 和 undefined 的相等比较
x == y:x 为 null, y为 undefined,则结果为 true1
2
3
4var a = dosomething();
if(a == null) {
// ...
}
条件判断仅在 dosomething() 返回 null 和 undefined 时才成立,除此之外都不成立,包括0、 false 和 “” 这样的假值。
对象和非对象直接的相等比较
x == y: x 是字符串或数字,y 是对象,则将 y 转换为 ToPrimitive(y) 进行比较。安全运用隐士强制类型转换
如果两边值中有 true 或 false,千万不要使用 ==。
如果两边值有[]、””或0,千万不要使用==。