JS检查数据类型的方法

先扣题~JS检查数据类型的方法如下:

  1. typeof xxx
  2. xxx instanceof 对象子类型
  3. (xxx).constructor === 对象子类型
  4. Object.prototype.toString.call(xxx)

具体猫腻见下文:

1.typeof

JS简单基本类型(语言类型)/文字形式	|JS复杂基本类型/构造形式
 - number							| - Number
 - string							| - String
 - boolean							| - Boolean
 - symbol							| - Array
 - null								| - Date
 - undefined						| - RegExp
 - object							| - Object
 									| - Error
 									| - 等等,详见MDN

复杂基本类型是对象的子类型,也被叫做内置对象、内置函数(也叫构造函数,用new产生的函数调用)。和简单基本类型(官方称语言类型)要区分开。

我们用typeof方法打印出的结果,都是小写字母,也就是简单基本类型。

typeof 1			// "number"
typeof '1'			// "string"
typeof true			// "boolean"
typeof Symbol()		// "symbol"
typeof null			// "object"
typeof undefined	// "undefined"
typeof fn(){}		// "function"
typeof {}			// "object"

以上有3处值得注意!

  1. "symbol"类型的值,是通过Symbol()这种类似于构造函数的方法创建出来的,但是其不需要new,因为Symbol作为构造函数来说它并不完整,故它不支持语法:“new Symbol()”。
  2. null 的type不是"null",而是"object"。原理是这样的, 不同的对象在底层都表示为二进制, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof 时会返回“object”。实际上是JS设计时的bug。
  3. 函数的类型是"function",不是"object"。

2. instanceof

借用《你不知道的事JS(上)》中的例子来 instanceof 和 typeof 的区别:

var strPrimitive = "I am a string";
typeof strPrimitive; // "string"
strPrimitive instanceof String; // false

var strObject = new String( "I am a string" );
typeof strObject; // "object"
strObject instanceof String; // true
// 检查 sub-type 对象
Object.prototype.toString.call( strObject ); // [object String]

下面这段话建议左右对照上文中的简单基本类型、复杂基本类型(看看对面是否有相同的单词,如number和Number)来理解。(引文里的构造形式,对应大写字母开头的对象子类型;文字形式,对应字面量,类似于var a = 1的表达方式。)

原始值 “I am a string” 并不是一个对象, 它只是一个字面量,并且是一个不可变的值。如果要在这个字面量上执行一些操作, 比如获取长度、访问其中某个字符等,则需要将其转换为 String 对象

之所以可以在字面量上直接访问属性或者方法,是因为引擎自动把字面量转换成相应的对象。对于number字面量上,boolean字面量来说也是如此。

null 和undefined 没有对应的构造形式, 它们只有文字形式。 相反, Date 只有构造, 没有文字形式。

对于 Object、 Array、 Function 和 RegExp来说, 无论使用文字形式还是构造形式, 它们都是对象不是字面量。 在某些情况下, 相比用文字形式创建对象, 构造形式可以提供一些额外选项。 由于这两种形式都可以创建对象, 所以我们首选更简单的文字形式。 建议只在需要那些额外选项时使用构造形式。

Error 对象很少在代码中显式创建, 一般是在抛出异常时被自动创建。 也可以使用 new Error(…) 这种构造形式来创建,不过一般来说用不着。

总结:

  • 字面量方式创建的"string",“number”,"boolean"数据使用 instanceof 会返回false
  • 引用数据类型(“object”)无论是字面量方式创建还是构造方式创建,使用 instanceof 只要后面对象子类型没跟错,就会返回true
  • Object是一切复杂基础类型的爸爸
    注:是不是和浅拷贝、深拷贝对上了号了!

3. constructor

constructor貌似能弥补instanceof中的一些不便,还是上面的例子

var strPrimitive = "I am a string";
typeof strPrimitive; 					// "string"
strPrimitive instanceof String; 		// false
strPrimitive.constructor === String; 	// true

正常情况下,constructor还是能正常显示类型的,但如果你测试的是一个对象(引用数据类型),那只要你把构造函数的prototype指向改一下,实例化对象的constructor立马翻脸不认人,详见实例、构造函数、函数对象的关系,是的!构造函数的prototype才是实例construtor的金主爸爸,随时可以换的~

4.Object.prototype.toString

此方法如果在自定义对象中未被覆盖,则返回 “[object type]”,其中 type 是对象的类型。这个类型指的很暧昧,从大多数结果类型名(有Date、Function等)以及打印形式(首字母大写)来看,这个类型是指复杂数据类型,但下面两个例子就很迷,不过不影响类型检测就是了。JS真的是一门很随便的语言啊~
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值