JavaScript中的类型判断

从JavaScript中的类型说起

JavaScript中有7种基本类型。还有引用类型(即通常说的对象)、函数类型。

判断数据类型的方法

1. typeof

typeof常用于判断基本数据类型,对于引用数据类型,全部返回object。对于函数,返回function。

特别的,对于typeof null,返回的是object。这是一个历史遗留bug。在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"

语法:

  • typeof [检测数据]:返回数据的类型名称

特点:

  • 对于基本类型,除 null 以外,均可以返回正确的结果。
  • 对于引用类型,除 function 以外,一律返回 object 类型。
  • 对于 null ,返回 object 类型。
  • 对于 function 返回 function 类型。
// 数值
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof(42) === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写
typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值

typeof 42n === 'bigint';


// 字符串
typeof '' === 'string';
typeof 'bla' === 'string';
typeof `template literal` === 'string';
typeof '1' === 'string'; // 注意内容为数字的字符串仍是字符串
typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串
typeof String(1) === 'string'; // String 将任意值转换为字符串,比 toString 更安全


// 布尔值
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换
typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean()


// Symbols
typeof Symbol() === 'symbol';
typeof Symbol('foo') === 'symbol';
typeof Symbol.iterator === 'symbol';


// Undefined
typeof undefined === 'undefined';
typeof declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === 'undefined';


// 对象
typeof {a: 1} === 'object';

// 使用 Array.isArray 或者 Object.prototype.toString.call
// 区分数组和普通对象
typeof [1, 2, 4] === 'object';

typeof new Date() === 'object';
typeof /regex/ === 'object'; // 历史结果请参阅正则表达式部分


// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String('abc') === 'object';

// 函数
typeof function() {} === 'function';
typeof class C {} === 'function'
typeof Math.sin === 'function';

2. instanceof

instanceof用来检测某一个实例的原型链上是否有这个类的原型属性。

语法:

  • [检测数据] instanceof [class]:返回true或false

特点:

  • 可以区分复杂数据类型
  • 只要在当前实例的原型链上,我们用其检测出来的结果都是true
  • 基本类型值检测繁琐,且检测不全(undefined, null, symbol)

原理:

  • 验证当前类的原型prototype是否会出现在实例的原型链__proto__上,只要在它的原型链上,则结果都为true。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,找到返回true,未找到返回false

3. constructor

constructor用来检测引用数据类型。

语法:

  • 检测数据.constructor === class

特点:

  • 适合使用在引用数据类型上
  • 原型链不会干扰

原理:

  • 构造函数原型上有一个 constructor 属性指向构造函数自身,如果在实例上使用 construtor 时,就会直接使用其构造函数原型的上的该属性,并指向其构造函数。
// 可以检测其构造函数
console.log([].constructor === Array); // true
console.log({}.constructor === Object);// true
function Person() { }
console.log(new Person().constructor === Person);// true

// 原型链不会干扰
console.log([].constructor === Object); // false

4. Object.prototype.toString.call()

这种判断数据类型的方法使用了原型链。

语法:

  • Object.prototype.toString.call(检测数据)

特点:

  • 适用于所有类型的判断检测

原理:

  • Object.prototype.toString表示一个返回对象类型的字符串,call()方法可以改变this的指向,那么把Object.prototype.toString()方法指向不同的数据类型上面,返回不同的结果
console.log(Object.prototype.toString.call("123"))   // --------> [object String]
console.log(Object.prototype.toString.call(123))     //--------> [object Number]
console.log(Object.prototype.toString.call(true))    //--------> [object Boolean]
console.log(Object.prototype.toString.call([1, 2, 3])) //--------> [object Array]
console.log(Object.prototype.toString.call(null))      //--------> [object Null]
console.log(Object.prototype.toString.call(undefined)) //--------> [object Undefined]
console.log(Object.prototype.toString.call({ name: 'Hello' })) //--------> [object Object]
console.log(Object.prototype.toString.call(function () { }))   //--------> [object Function]
console.log(Object.prototype.toString.call(new Date()))        //--------> [object Date]
console.log(Object.prototype.toString.call(/\d/))              //--------> [object RegExp]
console.log(Object.prototype.toString.call(Symbol()))          //--------> [object Symbol]

题目:判断一个数据是不是数组

  1. Array.isArray(obj)

    这个没什么好说的,内置对象的API。

  2. obj instanceof Array

    利用原型链

  3. Object.prototype.toString.call(obj)

    最靠谱的方法

  4. obj.constructor === Array

    constructor 属性返回对创建此对象的函数的引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值