数据类型
-
基本数据类型:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。 这是因为这些原始类型占据的空间是固定的,所以可将他们存储在较小的内存区域 – 栈中。这样存储便于迅速查寻变量的值。
-
引用数据类型:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存地址。 这是因为:引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。
js数据类型
- 基本数据类型 string,number,boolean,null,undefined,symbol
- 引用数据类型: object, function, array,Reg
typeof
-
typeof返回一个字符串,表示未经计算的操作数类型
-
判断基本数据类型。特例:
null的操作数类型是object -
引用数据类型返回object,特例:
function(){} 返回function
console.log(typeof 11) // number
console.log(typeof '11') // string
console.log(typeof true) // boolean
console.log(typeof undefined) // undefined
console.log(typeof []) // object
console.log(typeof {}) // object
console.log(typeof function name(params) {}) // function
console.log(typeof null) // object
instanceof作用
-
A instanceof B 某对象是否是构造函数的实例(玩的是原型链)
-
所以基本数据类型返回false,对象(引用数据类型)返回true
步骤概念
- 由于instance要检测是是,某对象。所以一定要有一个前置判断条件
- 左侧的__proto 是否和右侧的prototype一致。对象是否是构造函数的实例
- 如果不一致,会一直往上找。如果找到返回false,找不到,返回true
function _instanceof(L, R) {
if (L === null) {
return false
}
if (typeof L !== 'object' && typeof L !== 'function') return false
L = L.__proto__
R = R.prototype
while (L) {
if (L === null) return false
if (L === R) return true
L = L.__proto__
}
}
console.log('检测', _instanceof(null, Array)) // false
console.log('检测', _instanceof([], Array)) // true
console.log('检测', _instanceof('', Array)) // false
console.log('检测', _instanceof({}, Object)) // true
Object.prototype.toString.call()
console.log(Object.prototype.toString.call([])) // [object Object]
console.log(Object.prototype.toString.call({})) // [object Boolean]
console.log(Object.prototype.toString.call(true))// [object Boolean]
console.log(Object.prototype.toString.call(null))// [object Null]
console.log(Object.prototype.toString.call(undefined))// [object Undefined]
console.log(Object.prototype.toString.call('11'))// [object String]
console.log(Object.prototype.toString.call(11))// [object Number]
console.log(Object.prototype.toString.call(function () { }))// [object Function]
Object.prototype.toString 讲解
- Object.prototype.toString 会返回一个形如"[object XXX]"的字符串
- 对于Object.prototype.toString.call(arg),若参数为null或undefined,直接返回结果。
- 若参数不为null或undefined,则将参数转为对象,再作判断。对于原始类型,转为对象的方法即装箱,此处不赘述。
- 转为对象后,取得该对象的[Symbol.toStringTag]属性值(可能会遍历原型链)作为tag,如无该属性,或该属性值不为字符串类型,则依下表取得tag, 然后返回"[object " + tag + "]"形式的字符串。
封装成一个通用的方法
function getType(obj) {
let type = Object.prototype.toString.call(obj)
return type.split(' ')[1].replace(']', '')
}
console.log('检测', getType({})) // Object
console.log('检测', getType([])) // Arrary
console.log('检测', getType('11')) // String
console.log('检测', getType(11)) // Number
总结
-
typeof是小老弟,返回具体的数据类型,用来区分基本数据类型完全可以够用。但是用来区分引用数据类型就jj了
-
instanceof是专门用来判断引用数据类型的,是引用类型就返回true。不是就返回false。在手写instanceof的时候,配合上typeof,可以说就完美的解决了判断基本数据类型和引用数据类型。
-
万物皆对象,所以最后高明的Object出现了,他基本类型和引用类型都能判断,并且以[object xxx]的形式。返回具体的数据类型
-
说到最后,程序员是写代码的,你们type,instanceof,Object.prototype.toString.cal.终究不过是工具。我们封装一个方法,直接调用方法求类型多方便。