JavaScript基本类型总结
引自
我的个人博客,原文链接:JavaScript基本类型总结
背景
最近仔细看了看Javascript的变量相关章节,包括网道阮一峰大神写的 JavaScript教程,以及被誉为JS圣经的《JavaScript权威指南》,故对变量的基础类型做一个总结
变量有什么类型?
JS中的数据类型总体分为两类:原始类型和对象类型
原始类型
包括数字、字符串、布尔值、null、undefined
对象类型
除了原始类型,其他都是对象类型,Object(普通对象)、Function(函数)、Array(数组)
PS: 虽然字符和数字也能通过对象的方式调用方法,但是这只是JS自动进行的包装对象,比如:
'1,2'.split();// '1,2' 会被转换为 String('1,2')
var a = 3.1415926;
var b = a.toFixed(2)// a 会被转换为 Number(a)
var c = new Number(111); c === 111// false 包装对象与原属性不全等
Number(111) === 111 // true, Number(111) 是显示转换的意思,结果是 111,所以全等
var str = 'test';
str.number = 10;// 包装String对象
console.log(str.number);// undefined,注意这个地方,包装对象的生命周期只在那一个语句,下一个语句就没了
var arr = [];
arr.number = 123;
console.log(arr.number);// 123,这里是因为 [] 本来就是对象,与包装对象不同
包装对象的详解可以参考如下博客:blog.csdn.net/lhjuejiang/article/d...
类型转换
由于JS是一个弱类型的语言,所以在不同数据类型的数据进行比较或者操作的时候,需要进行类型转换,类型转换分强制转换(也称显式转换)以及自动转换(也称隐式转换)
强制转换
使用 Number() String() Boolean() 等构造函数进行强制转换,也相当于显示新增了包装对象,相比 parseInt(),parseFloat() 等辅助函数更加严格
Number('1') // 1
Number(true) // 1
Number(false) // 0
Number('1.2e8') // 120000000 PS:科学计数法
Number('0b1001')// 9 PS:二进制
Number('0xF') // 15 PS:十六进制
Number('0o777') // 511 PS:八进制
Number('1x') // NaN
// valueOf 用于返回对象自身,默认 return this,如果返回对象则调用原对象的 toString() 方法,如果 toString() 依旧返回对象,则报错无法转换
Number({
valueOf: function() {
return 123;
}
}) // 123
Number({
valueOf: function() {
return {}
},
toString: function() {
return {}
}
})// 报错 Uncaught TypeError: Cannot convert object to primitive value
String(true) // 'true'
String(1.) // '1'
String(1.1) // '1.1'
String(-0) // '0'
String(-Infinity) // -Infinity
String(Infinity) // Infinity
Boolean('') // false
Boolean(0) // false
Boolean(null) // false
Boolean(NaN) // false
Boolean(undefined) // false
Boolean([]) // true PS:除了上边的,其他转出来都是 true
Boolean({}) // true
自动转换
JS在不同类型数据互相运算时,非布尔值求布尔值,非数值类型使用 + – * / ,会自动根据场景调用相应的强制转换函数,既能转为字符又能转为数字时,优先数字
自动转Boolean
在需要用到布尔判断时,会导致此转换,比如 (if/else、三目运算符之类的)
if (
'' == false &&
null == false &&
undefined == false &&
0 == false &&
NaN == false
){
console.log(111);// true
}
[] ? 111 : 000 // 111
自动转数字
涉及 + – * / 等操作会转换为数字
1 + '2' // 3
1 + 's' // NaN
true + 1 // 2
'c' - 1 // NaN
自动转字符
字符 + 非字符 会被转换为字符串
'abc' + 1 // abc1
'1' + 0 // 10
'5' + undefined // 5undefined
'5' + function(){} // 5function(){}
如何检查变量类型
JavaScript是一个弱类型语言,我们可以用内置的三种方法判断一个值到底属于什么类型
- typeof 运算符
- instanceof 运算符
- Object.prototype.toString 方法
typeof判断变量类型的各种情况
typeof 123 // number
typeof '123' // string
typeof false // boolean
f = function() {}
typeof f // function
typeof undefined // undefined
typeof xxxxx // 未定义变量不报错,返回 undefined
typeof {} // object
typeof window // object
typeof [] // object,数组的typeof是object
typeof null // object,null的typeof也是object
需要注意的点:数组、null 调用 typeof 都是 object。因为在JS中,数组本质上是一种特殊的对象,而null是因为最开始的JS把null作为对象的一种特殊值,为了向前兼容,就一直 typeof null === ‘object’ 了
instanceof 通过原型链判断数据类型
instanceof 返回一个 Boolean,表示对象的原型链中是否存在某个构造函数(原始定义:对象是否为某个构造函数的实例)。
关于原型链,这里简单提及下,一个对象的 prototype 都指向其构造函数的 prototype,其中有一个方法 Object.getPrototypeOf 返回对象的原型,最终的最终都会指向 Object,而 Object.prototype = null,整个原型链到了尽头,原型链的更为详细的介绍可点击:参考博客
一些实例如下:
[] instanceof Array // true 因为原型链里有 Array 这个构造函数
[] instanceof Object // true 因为原型链里有 Object 这个构造函数
Array instanceof Object // true,因为Array是一个特殊的对象
[] instanceof null // 报错,Right-hand side of 'instanceof' is not an object,因为null不是个对象
var func = function() {}
func instanceof Function // true,原型链中有Function
func instanceof Object // true,Function的原型是 Object
Function instanceof Object // true,函数是一个特殊对象
Object.prototype.toString()
toString() 用于返回一个对象的字符串形式,用于在自动类型转换时得到想要的字符形式。一些样例具体如下:
var obj = {};
obj.toString() // [object Object]
var obj2 = {name: 'xxx'};
obj2.toString = function() {
return 'Hello '+this.name
}
obj2.toString() // Hello xxx
obj2 == 'Hello xxx' // true
var obj3 = []
obj3.toString() // '' 空字符串,因为数组是空的
var obj4 = [1, 2, 3]
obj4.toString() // '1,2,3'
由于对象的 toString 可以被重载,如果要用于类型判断的话,需要用到 Object.prototype.toString.apply(obj)
的方式,显示格式 [object 构造函数],比如 [object Object]
, [object Number]
, [object String]
,[objct Function]
,不过有个问题是无法精确判断 字符对象 和 字符串,因为返回都是 [object String]
apply
是Function
对象的一个方法,可以更改函数执行上下文,意思是执行Object.prototype.toString
函数,但是执行过程中的this
指向外部注入的obj
,如果还是看不明白可以参考博主之前写的另外一篇博客 JS中Function.apply() 的骚操作
Object.prototype.toString.apply({}) // [object Object]
Object.prototype.toString.apply([]) // [object Array]
Object.prototype.toString.apply('') // [object String]
Object.prototype.toString.apply(String('')) // [object String]
Object.prototype.toString.apply(123) // [object Number]
Object.prototype.toString.apply(NaN) // [object Number]
Object.prototype.toString.apply(String) //[object Function]
Object.prototype.toString.apply(function(){return 111}) //[object Function]
Object.prototype.toString.apply(undefined)// [object Undefined]
Object.prototype.toString.apply(null) // [object Null]
Object.prototype.toString.apply(true) // [object Boolean]
总结
变量类型是JS的基础之一,也是平时很容易忽视的地方,稍不注意就容易产生莫名其妙的BUG,特此总结
本作品采用《CC 协议》,转载必须注明作者和本文链接