数据类型判断

typeof

typeof 操作符返回一个表示数据类型的字符串,它可以应付常规场景下的数据类型判断。对基本数据类型 undefined, boolean, string, number 和引用数据类型 function 都可以正确判断,但是对 null,数组,对象则统一返回 “object”。也就是说,typeof 不适合用来判断引用数据类型。

var a = 1
typeof a // "number"
var b = [1,2,3]
typeof b // "object"
var c = {}
typeof c // "object"

instanceof

instanceof 解决了上述问题,它的原理就是判断右操作数(通常是构造函数)的原型对象是否出现在左操作数(通常是实例)的原型链上,如果在则返回 true。据此可以判断引用数据类型具体是哪种类型。

var b = [1,2,3]
b instanceof Array // true
var c = {}
c instanceof Object // true

需要注意的是,instanceof 对于不是通过 new 创建的基本数据类型无法做出正确的判断:

var a = 1
a instanceof Number // false

这是因为此时的 a 仅仅是一个基本类型的值,而不是实例对象,如果我们通过 new 创建 a,那么就能正确判断

var a = new Number(1);
a instanceof Number // true

结合 instanceof 的原理其实就很好理解其中原因了。

>> 另外要注意,instanceof 这个方法并非百试百灵 —— 假定脚本中有多个全局环境,例如 html 中有多个子 iframe,那么对于每一个全局环境而言,它都有自己版本的构造函数,进而有自己版本的原型链。instanceof 左右两边的操作数来自于不同全局环境时,即使实例和构造函数对应,也只会返回 false。

Object.getPrototypeOf()

let arr = [1,2];
console.log(Array.prototype.isPrototypeOf(arr)); // true

利用原型链。存在同上问题。

isPrototypeOf()

let arr = [1,2];
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true

利用原型链。存在同上问题。

Object.prototype.toString.call()

let arr = [1,2];
`Object.prototype.toString.call(arr)`; //"[object Array]"

这个方法基本很完善,原理就是:在任何值上调用 Object 原生的 toString() 方法,都会返回一个格式为 [object NativeconstructorName] 的字符串。据此可以准确判断任何值的数据类型。

这里注意几个点:

  1. arr 作为对象,也是 Object 的一个实例,为什么不直接使用 arr.toString()?这是因为它的这个方法被重写了,即 Array.prototype.toString()。在使用 arr.toString() 的时候,它优先在原型链上找到并调用了重写的方法,最后输出的是 "1,2"
  2. 对象字面量调用 toString() 的时候则依然输出 "[object Object]",这是因为它没有重写这个方法,所以找到的是 Object.prototype 的该方法。
  3. 同样的,函数对象的 toString() 方法也被重写了,即 Function.prototype.toString()。调用的时候返回一个表示当前函数源代码的字符串。当对内置函数对象调用该方法时,返回如下格式的字符串:
Object.toString();

// "function Object() {
//    [native code]
// }"

Array.toString(); 
// "function Array() { 
//    [native code] 
// }"

实际上,这里的 Object 是构造函数,既然是函数,就可以看作是 Function 构造函数实例化的对象,因此这里相当于函数对象调用了 toString() 方法,也就是调用的 Function.prototype.toString() 方法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏业余草

Java 必会10大的经典算法

原文链接:https://github.com/hustcc/JS-Sorting-Algorithm

13010
来自专栏业余草

讲真,下次再也不敢随便改 serialVersionUID 了

原文链接:https://url.cn/5kiGWwk

9940
来自专栏用户5521492的专栏

一文看懂Java序列化之serialVersionUID

serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进...

8210
来自专栏业余草

面试遇到Java 里的 for (;;) 与 while (true),哪个更快?

原文链接:http://www.zhihu.com/question/52311366/answer/13009034...

9320
来自专栏京程一灯

React VS Vue:2020年应该选哪个?[每日前端夜话0xD3]

Javascript 框架以及 HTML 和 CSS 已成为每个现代软件项目前端开发的重要组成部分。2020 年将会是为你的 Web 项目选择正确的 javas...

17310
来自专栏深圳java培训

深圳大数据培训学习:继承--【千锋】

也可以把单个方法或者字段声明为final,以确保它不能被重写,注意和Java的不同,Java中final修饰的字段意味着不可变。

7020
来自专栏Zaqdt_ACM

POJ 2752 Seek the Name, Seek the Fame(KMP求公共前后缀)

题意是给了一个字符串,求出前i位的前缀刚好是后i位的后缀,输出这些位置,比如abcab当i为2的时候前缀为ab后缀也为ab

6410
来自专栏Java技术栈

Java 14 可能带来什么新特性?

JDK/Java 13 在一个月前已经发布,该版本带来了 5 大新特性,笔者观察到其中的 Text Blocks(文本块)特性似乎被讨论最多。

7910
来自专栏python编程军火库

5分钟面试指南(第十四篇 听说你要重构项目)

本部分我们会为大家提供一些python初级工程师在面试过程中遇到的常见的面试题目,期望达到的效果:

8930
来自专栏SpringCloud专栏

分布式事务之Seata中间件原理及流程详细分析

原文链接:https://blog.csdn.net/f4761/article/details/89077400

12020

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励