主要类型判断的方法:
typeof
instanceof
* Object.prototype.toString.call()
* Array.isArray()
typeof 只能判断基本类型:number string object undefined boolean
typeof
console.log(typeof(2),'test') //number
console.log(typeof(true),'test') //boolean
console.log(typeof('2'),'test') //string
console.log(typeof([]),'test') //object
console.log(typeof({}),'test') //object
console.log(typeof(null),'test') //object
console.log(typeof(undefined),'test')
//undefined
function f() {}
console.log(typeof(f),'test') //function
typeof 没有办法判断 引用类型
instanceof(以为很简单,却最复杂)
判断变量是否为某个对象的实例,返回值为true或者false
let o = {}
console.log(o instanceof Object) //true
let a = []
console.log(a instanceof Array) //true
function f() {}
console.log(f instanceof Function) //true
console.log(true instanceof Boolean) //false
console.log(1 instanceof Number) //false
console.log('1' instanceof String) //false
大家可以看到当涉及到值类型时,就会显示"不太正常"
var str = new String('000')
var str2 = '000'
console.log(str1 instanceof String) //true
console.log(str2 instanceof String)
//false
console.log(str) //String{"000"}
console.log(str2) //000
大家会发现不同方式的创建字符串,instanceof 却不一样?
所以instanceof 的工作原理究竟是什么呢?
规范定义的该运算符
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
var O = R.prototype;// 取 R 的显示原型
L = L.__proto__;// 取 L 的隐式原型
while (true) {
if (L === null)
return false;
if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
return true;
L = L.__proto__;
}
}
只有数据类型的隐式类型和显式类型绝对相等时,才会返回true
这就设计到了原型链了
这两种方式都可以创建字符串,但是str是在堆内存中开辟一片新空间存放新对象,是有原型链的,str2是放在常量池中(没有原型链的).
1.如果常量池中已经有字符串常量”aaa”
通过方式二创建对象,程序运行时会在常量池中查找”aaa”字符串,将找到的“aaa”字符串的地址赋给a。
通过方式一创建对象,无论常量池中有没有”aaa”字符串,程序都会在堆内存中开辟一片新空间存放新对象。
2.如果常量池中没有字符串常量”aaa”
通过方式二创建对象,程序运行时会将”aaa”字符串放进常量池,再将其地址赋给a。
通过方式一创建对象,程序会在堆内存中开辟一片新空间存放新对象,同时会将”aaa”字符串放入常量池,相当于创建了两个对象。
所以 new出来的会有原型属性.而直接赋值的则没有.
还有:instanceof适合在单一的全局执行环境下,而在两个以及以上不同的执行环境中则不使用,适合用Array.isArray方法检测
Array.isArray()
let arr = [1,2,3]
console.log(Array.isArray(arr)) // true
Object.prototype.toString.call()
console.log(Object.prototype.toString.call('1'))
console.log(Object.prototype.toString.call(1))
console.log(Object.prototype.toString.call(true))
console.log(Object.prototype.toString.call(null))
console.log(Object.prototype.toString.call(undefined))
console.log(Object.prototype.toString.call([]))
var set = new Set();
console.log(Object.prototype.toString.call(set))
var map = new Map();
console.log(Object.prototype.toString.call(map))
console.log(Object.prototype.toString.call({}))
function f2(){}
console.log(Object.prototype.toString.call(f2))
//output
[object String]
[object Number]
[object Boolean]
[object Null]
[object Undefined]
[object Array]
[object Set]
[object Map]
[object Object]
[object Function]
所以用 Object.protoType.toString.call() 更准确
记住Object.protoType.toString() 去查看类型都是Object,所以要用Object.protoType.toString.call()