Object.prototype:判断对象类型的方式

开发 前端
数据类型的判断是一个老生长谈的问题了,Object.prototype.toString.call()是 JavaScript 中用于准确判断数据类型的方法。

数据类型的判断是一个老生长谈的问题了,不多废话,直接先说最优的方法。

Object.prototype.toString.call

Object.prototype.toString.call()是 JavaScript 中用于准确判断数据类型的方法。

toString()本身是Object原型上的一个方法,用于返回对象的字符串表示形式。而通过call()方法可以改变toString()执行时的this指向,让我们能够获取任意对象准确的类型信息。

如果你需要判断一个数据是否是一个普通的对象而不是数组、函数等其他类型,推荐使用 Object.prototype.toString.call 方法。

且无论对于基本数据类型,还是复杂数据类型,都是准确有效的。

function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
}

// 测试代码
console.log(isPlainObject({})); // true
console.log(isPlainObject([])); // false
console.log(isPlainObject(function() {})); // false

下面再聊聊其它几种方法,了解即可。

typeof

优点:

简单快速:是 JavaScript 原生提供的操作符,语法简单,易于理解和使用。对于基本数据类型的判断非常直接,如typeof 1返回"number",typeof "string"返回"string",typeof true返回"boolean",能快速区分这些常见的基本类型。

兼容性好:在各种 JavaScript 环境中都能稳定使用,几乎所有的浏览器和 JavaScript 运行时都支持typeof操作符,在代码的跨平台和跨浏览器场景中不用担心兼容性问题。

缺点:

对复杂对象类型判断不准确:对于复杂的数据类型,typeof的判断能力有限。例如,typeof []返回"object",不能准确地识别出这是一个数组;typeof new Date()也返回"object",无法区分出是日期对象;typeof /abc/同样返回"object",不能判断是正则表达式。这在需要精确判断复杂对象类型的场景中会导致问题。

无法判断自定义对象类型:如果是自定义的构造函数创建的对象,typeof只能返回"object",不能提供关于该对象具体构造函数的信息。例如,function Person() {}; var p = new Person(); typeof p返回"object",不能判断这个对象是由Person构造函数创建的。

constructor

优点:

能够识别对象的构造函数:可以直接获取创建对象的构造函数。例如,[].constructor返回Array函数,new Date().constructor返回Date函数,(/abc/).constructor返回RegExp函数。对于自定义构造函数创建的对象也能准确识别,如function Person() {}; var p = new Person(); p.constructor返回Person函数,这有助于明确对象的来源。

缺点:

可被篡改:对象的constructor属性是可以被修改的,这可能导致错误的判断。例如,var arr = []; arr.constructor = function() {}; arr.constructor就不再指向Array函数,使得基于constructor的类型判断失效。

对于原始数据类型有局限性:原始数据类型本身没有constructor属性(在 JavaScript 中,原始数据类型在某些操作下会进行自动装箱,如1..constructor会返回Number函数,但这种方式不够直观和稳定),在判断原始数据类型时不是很方便,不如typeof直接。

instanceof

优点:

基于原型链判断对象关系:可以准确判断一个对象是否是某个构造函数的实例,是基于对象的原型链进行判断的。例如,[] instanceof Array返回true,new Date() instanceof Date返回true,能很好地判断对象与构造函数之间的继承关系。在面向对象编程和处理对象实例关系的场景中非常有用。

缺点:

受原型链影响易出错:如果对象的原型链被修改,可能会导致错误的判断。例如,如果有一个对象obj,手动将其原型设置为Array.prototype,那么obj instanceof Array会返回true,但实际上这个对象可能并不是按照常规方式通过Array构造函数创建的。

不能用于判断原始数据类型:instanceof只能用于判断对象是否是某个构造函数的实例,对于原始数据类型(如数字、字符串、布尔值等)不能进行判断,因为原始数据类型不是对象,没有原型链的概念。例如,instanceof Number在严格意义上不符合instanceof的使用规则,返回的结果可能会让人误解(实际上在 JavaScript 内部对原始数据类型进行自动装箱等操作时,instanceof Number返回false)。

责任编辑:姜华 来源: 程序员大澈
相关推荐

2014-01-22 09:46:42

JavaScript数组

2016-12-21 09:35:55

JavaScript原生数组函数

2020-09-23 07:47:14

Java方式类型

2009-11-30 16:40:38

PHP object对

2024-05-20 08:38:25

typeobjectPython

2022-04-16 13:59:34

Vue.jsJavascript

2010-02-01 16:14:33

Python PySt

2024-06-12 09:52:00

2010-10-09 09:56:51

JavaScriptObject对象

2010-02-01 16:07:23

PyStringObj

2020-07-15 10:20:32

前端prototype__proto__

2022-01-15 10:01:15

Javascript 高阶函数前端

2020-08-26 14:20:24

prototype__proto__ 前端

2021-09-14 07:26:25

JavaScript迭代对象

2021-09-03 10:00:00

JavaScript迭代对象

2024-11-14 13:15:22

JavaScript可迭代数组

2011-05-10 10:00:41

克隆

2021-04-29 08:28:24

架构参数传递

2023-02-21 15:19:25

JavaScriptypeof数据类型

2012-12-24 09:45:21

点赞
收藏

51CTO技术栈公众号