检测数据类型
# typeof
总结:
数组
、对象
、null
都会被判断为object,其他判断都正确的类型。
- 可以检测基本数据类型
null
会检测为Object
,因为null也是一个空的引用对象- 复杂数据类型只能检测
function
和Object
情况说明:
- 数组:这是因为 JavaScript 中的数组实际上是一种特殊的对象。
- null:这是一个历史遗留问题,在 JavaScript 的早期实现中存在的一个错误,可以理解为
null
表示一个空或不存在的对象引用。
typeof undefined // "undefined"
typeof null // "object"
typeof 1 // "number"
typeof "1" // "string"
typeof Symbol() // "symbol"
typeof function() {} // "function"
typeof {} // "object" typeof作用于未定义的变量不会报错,会返回一个undefined
!typeof判断null为object
是JS语言的一个历史遗留问题,在第一版JS代码中用32比特来存储值,通过值的1-3
位来识别类型,前三位为000
表示对象类型。而null
是一个空值,二进制表示都位0,所以前三位也就是000
,所以导致typeof null
返回Object
。
!typeof判断强制转换
注意Number和String作为普通函数调用的时候,是把参数转化为相应的基本数据类型,也就是类似于做一个强制转换的操作,而不是默认当作构造函数来调用。
typeof Number(1) //number
typeof String("1") //StringArray(1,2,3)等价于new Array(1,2,3)
但是,Array()
等价于new Array()
,所以创建的是一个对象。
!typeof判断构造函数
类似于typeof new Number(1)
这些new Number(1)
和 new String(1)
都是通过 new
操作符创建的构造函数的实例,而构造函数创建的是对象。
typeof new Number(1) // "object"
typeof new String(1) // "object"
# instanceof
总结:只能正确判断引用数据类型 ,不能判断基本数据类型。
情况说明:
instanceof
可以正确判断对象的类型,其内部运行机制是判断原型链中能否找到该类型的原型。
当使用 instanceof 时,它会按照以下步骤进行:
1. 检查右侧的构造函数的 prototype 属性。
2. 然后沿着左侧对象的 __proto__(或者使用 Object.getPrototypeOf() 方法)指针向上遍历其原型链。
3. 如果在原型链的某个地方找到了与右侧构造函数的 prototype 相同的对象,则返回 true。
4. 如果遍历到原型链的顶端(即 Object.prototype),还没有找到匹配的 prototype,则返回 false。
!typeof和instanceof区别
返回值不同:
typeof
返回一个运算数的基本类型instanceof
返回是布尔型
判断的数据类型不同:
t
能正确判断基本数据类型,但是无法正确判断除了function外的数据类型i
不能判断基本数据类型,但是可以准确判断引用数据类型
!instanceof的实现原理*
instanceof
运算符适用于检测构造函数的prototype
属性上是否出现在某个实例对象的原型链上。
instanceof
运算符的原理是基于原型链的查找。当使用obj instanceof Construtor
进行判断的时候,JS引擎会从obj
原型链上查找Constructor。prototype
是是否村站,如果存在返回true
,否则继续在原型链上查找。如果查找到的原型链的顶端仍然没有找到,则返回false
。
instanceof
运算符只能用于检查某个对象是否是某个构造函数的实例,不能用于基本类型的检查。
# toString ?
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
# constructor
总结:是一个对象的内置属性,它包含了一个指向创建该对象的构造函数的引用,也可以检测出字面量方式创建的对象类型,因为字面方式创建,实际由对应类创建而出。
例子:
//-------例子1--------//
function Person(name) {this.name = name;
}var person = new Person('Kimi');
console.log(person.constructor === Person); // true
console.log(person.constructor === Function); // true,因为Person是函数的实例//-------例子2--------//
function Animal(name) {this.name = name
}const dog = new Animal('大黄')console.log(dog.constructor === Object) // false
console.log(dog.constructor === Animal) // true//-------例子3--------//const arr = []console.log(arr.constructor === Array)//Array
# isArray
总结:用于检测数组
const arr = []
Array.isArray(arr)
杂题
!如何判断null
如果想要判断null
,可以直接使用全等运算符===
或者使用Object.protptype.toString方法
// 使用`===`全等运算符来判断
let a = null
a === null // true// 使用 Object.prototype.toString 方法
let a = null;
let result = Object.prototype.toString.call(a);
console.log(result); // 输出 '[object Null]'