面试题:四种判断数据类型的方法

您所在的位置:网站首页 变应力的分类有哪几种方法 面试题:四种判断数据类型的方法

面试题:四种判断数据类型的方法

2024-07-11 18:32| 来源: 网络整理| 查看: 265

前言

JavaScript 是一种弱类型或者说动态类型,这就意味着你不需要提前声明变量的类型,在程序运行的过程中,类型会被自动确定。这就意味着你可以使用同一个变量保存不同类型的数据:

var data = 5 // data is Number now data = '5' // data is String now data = true // data is Boolean now .......

相信不管是在学习还是平常写业务的过程中,或多或少的都会碰到类似于--- 如何判断数据类型 的这种问题。尤其是在面试中,经常被问到 --- 请说出判断数组的几种方法 你知道判断数据类型有哪几种方法等等。

虽然看起来仅仅只是判断数据类型的方法,但是涉及到数据类型,原型链等各种js基础,话不多说,直接开始吧。

数据类型

最新的 ECMAScript 标准定义了 8 种数据类型:

7中原始类型: Boolean Null Undefined Number BigInt String Symbol Object 原始值

--- 其实我也是第一次知道原始值这个概念的

除Object 以外的所有类型(基本类型)都是不可以变的(值本身无法被改变) 例如:js中字符串是不可变的(js对字符串的操作返回了一个新字符串,但是原始字符串并没有被改变),我们称这些类型的值为“原始值”。

Boolean

对于布尔类型,永远只有true和false两个值。

Null

null 是一个字面量,不像 undefined ,它不是一个全局对象的一个属性。null 是表示缺少的标识,指示变量未指向任何对象。把 null 作为尚未创建的对象,也许更好理解。

在 API 中,null 常在返回类型应是一个对象,但没有关联的值的地方使用。

Undefined

一个没有被赋值的变量会有个默认值 undefined; undefined是全局对象的一个属性。

Number

根据 ECMAScript 标准,JavaScript 中只有一种数字类型:基于 IEEE 754 标准的双精度 64 位二进制格式的值(-(2^53 -1) 到 2^53 -1)。它并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:+Infinity,-Infinity 和 NaN (非数值,Not-a-Number)。

BigInt

使用 BigInt,可以安全地存储和操作大整数. 常常通过在整数末尾附加 n 或调用构造函数来创建的。

const a = BigInt('43243242424242424242342432') // 43243242424242424242342432n const b = 43243242424242424242342432n // 43243242424242424242342432n String

字符串的长度是它的元素的数量。字符串一旦被创建,就不能被修改。但是,可以基于原始字符串的操作来创建新的字符串。例如:

String.concat() 拼接字符串

插一个问题:'1'.toString()为什么可以调用?

let a = new Object('1'); a.toString(); console.log('-----a',a); // [String: '1'] a = null console.log('-----a最终',a); // null 第一步:创建Object类实例。注意为什么不是String ?由于Symbol和BigInt的出现,对它们调用new都会报错,目前ES6规范也不建议用new来创建基本类型的包装类。 第二步:调用实例方法。 第三步:执行完方法立即销毁这个实例。 Symbol

Symbol 是ES6新增的一种基本数据类型。我们可以通过调用内置函数 Symbol() 创建,这个函数会动态的生成一个匿名、全局唯一的值。

const a = Symbol(); const b = Symbol(); a === b // false const c = Symbol('c'); // Symbol(c)

Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。

Symbol最大的用处就是:避免对象的键被覆盖。

基本数据和引用数据的区别 基本数据类型 按值访问,可操作保存在变量中实际的值 值被保存在 栈内存 中,占据固定大小的空间 引用数据类型 引用类型的值是按引用访问的 保存在堆内存中的对象,不能直接访问操作对象的内存空间

回归正题,下面来说说判断数据类型的方法👇

typeof typeof '5' // string typeof 5 // number typeof null // object typeof undefined // undefined typeof true // boolean typeof Symbol('5') // symbol typeof 5n // bigint typeof new Object(); // object typeof new Function(); // function

上面的例子,对于基本数据类型来说,除了null返回的是object,其他都可返回正确的类型。 调用null为空,是因为

null被认为是一个空对象,因此返回了object 因为任何对象都会被转化为二进制,null转为二进制则表示全为0,如果前三个均为0,js就会把它当作是对象,这是js早期遗留下来的bug

所以typeof:

适用于判断(除null)基础类型, 判断引用类型,除了function 全返回object类型 instanceof 只能用来判断变量的原型链上是否有构造函数的prototype属性(两个对象是否属于原型链的关系),不一定能获取对象的具体类型 Instanceof 不适用判断原始类型的值,只能用于判断对象是否从属关系 [] instanceof Array; // true [] instanceof Object; // true function Person() {}; const person = new Person(); person instanceof Person; // true person instanceof Object; // true

首先来分析一下,为什么 [] instanceof Array 为true。

首先,[].proto 的原型 是指向Array.prototype 的,说明两个对象是属于同一条原型链的,返回true 同理,从代码中可以得知person instanceof Person也是返回true的,那么为什么person instanceof Object也为true呢? 基于原型链的原理:从实例对象的构造函数的原型开始向上寻找,构造函数的原型又有其原型,一直向上找,直到找到原型链的顶端Object.prototype为止。如果没有,则返回null 可以看出,person和Object是属于原型链的关系,所以返回true

注意:空对象{}的判断问题

let obj1 = {} console.log(obj1 instanceof Object) // true let obj2 = Object.create(null) console.log(obj2 instanceof Object) // false let obj3 = Object.create({}) console.log(obj3 instanceof Object) // true constructor

原理:每一个实例对象都可通过constructor来访问它的构造函数,其实也是根据原型链的原理来的。

'5'.__proto__.constructor === String // true [5].__proto__.constructor === Array // true undefined.__proto__.constructor // Cannot read property '__proto__' of undefined null.__proto__.constructor // Cannot read property '__proto__' of undefined

由于undefined和null是无效的对象,因此是没有constructor属性的,这两个值不能用这种方法判断.

toString

Object.prototype.toString方法返回对象的类型字符串,因此可用来判断一个值的类型。

因为实例对象有可能会自定义toString方法,会覆盖Object.prototype.toString,所以在使用时,最好加上call

所有的数据类型都可以使用此方法进行检测,且非常精准

Object.prototype.toString.call('5') // [object String] Object.prototype.toString.call(5) // [object Number] Object.prototype.toString.call([5]) // [object Array] Object.prototype.toString.call(true) // [object Boolean] Object.prototype.toString.call(undefined) // [object Undefined] Object.prototype.toString.call(null) // [object Null] Object.prototype.toString.call(new Function()); // [object Function] Object.prototype.toString.call(new Date()); // [object Date] Object.prototype.toString.call(new RegExp()); // [object RegExp] Object.prototype.toString.call(new Error()); // [object Error] 总结 typeof 适合基本类型和function类型的检测,无法判断null与object instanceof 适合自定义对象,也可以用来检测原生对象,在不同的iframe 和 window间检测时失效,还需要注意Object.create(null)对象的问题 constructor 基本能判断所有类型,除了null和undefined,但是constructor容易被修改,也不能跨iframe使用 tostring能判断所有类型,可将其封装为全能的DataType()判断所有数据类型


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3