2021-03-24

typeof和instanceof的区别是什么?有哪些实际作用?

JavaScript有三种方法,可以确定一个值到底是什么类型。

  • typeof 运算符
  • instanceof 运算符
  • Object.prototype.toString 方法

typeof 运算符

typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。 主要用于判断数据是不是基本数据类型:

  1. 原始类型
  2. 函数
  3. undefined
  4. object

1. 原始类型

typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"

2. 函数

function f() {}
typeof f
// "function"

3. undefined

undefined 和没有用 var 声明的变量,用typeof 返回的是 undefined

typeof undefined
// "undefined"
var x
typeof x
// "undefined"
y
// ReferenceError: y is not defined
typeof y
// "undefined"

这里y没有用var声明,直接使用就会报错,但是用typeof就不报错,而是返回undefined。 实际编程中,这个特点通常用在判断语句。

// 错误的写法
if (v) {
  // ...
}
// ReferenceError: v is not defined

// 正确的写法
if (typeof v === "undefined") {
  // ...
}

4. object

除了以上三种情况,其他情况都返回object

typeof window // "object"
typeof {} // "object"
typeof [] // "object"
typeof null // "object"

注意

  • 空数组[]的返回值是object,这表示,JavaScript内部,数组本质上是一种特殊的对象。
  • null的返回值是object,这是由于历史原因造成的,1995年JavaScript语言的第一版,所有值都设计成32位,其中最低的3位用来表述数据类型,object对应的值是000。当时,只设计了五种数据类型(对象、整数、浮点数、字符串和布尔值),完全没考虑null,只把它当作object的一种特殊值,32位全部为0。这是typeof null返回object的根本原因。 为了兼容以前的代码,后来就没法修改了。这并不是说null就属于对象,本质上null是一个类似于undefined的特殊值。

instanceof 运算符

instanceof 是判断变量是否为某个对象的实例,返回值为truefalse

var o = {};
var a = [];

o instanceof Array // false
a instanceof Array // true
a instanceof Object // true

typeof 对数组 [] 和对象 {} 的返回值都是Object,无法区分数组和对象,但是instanceof可以区分。 注意: 数组Array是对象Object的一个子类,所以a instanceof Object的返回值是 true

Object.prototype.toString

在很多情况下,我们可以使用instanceof运算符或对象的constructor属性来检测对象是否为数组。例如很多JavaScript框架就是使用这两种方法来判断对象是否为数组类型。 但是检测在跨框架(cross-frame)页面中的数组时,会失败。原因就是在不同框架(iframe)中创建的数组不会相互共享其prototype属性

而跨原型链调用toString()方法:Object.prototype.toString(),可以解决上面的跨框架问题。 这是对象的一个原生原型扩展函数,用来精确的区分数据类型 当Object.prototype.toString(o)执行后,会执行以下步骤:

1)获取对象o的class属性。 2)连接字符串:"[object “+结果(1)+”]" 3)返回 结果

并且我们会发现,typeof来判断数据类型其实并不准确。比如数组、正则、日期、对象的typeof返回值都是object,这就会造成一些误差。 所以在typeof判断类型的基础上,我们还需要利用Object.prototype.toString方法来进一步判断数据类型。

使用总结

typeof和instanceof都是用来检测变量类型的操作符,二者的区别在于

typeof是判断变量是什么基本类型的; instanceof是判断对象到底是什么类型的;

跨原型链调用toString()方法:Object.prototype.toString(),可以解决跨框架问题。 这是对象的一个原生原型扩展函数,可以用来精确的区分数据类型

WRITTEN BY

lidong

鄂ICP备20003892号Copyright © 2017-2023 leedong.cn

ABOUT ME

Hello,这里是「我的心情永不立冬」
一个想到什么就做什么的个人站点,所有内容纯主观、有偏见