优秀的编程知识分享平台

网站首页 > 技术文章 正文

JavaScript数据类型及检测方法(javascript的数据类型有哪些?)

nanyue 2024-07-20 00:09:47 技术文章 6 ℃

一、数据类型检测方法

在js中,有四种用于检测数据类型的方式,分别是:

  1. typeof 用来检测数据类型的运算符
  2. instanceof 检测一个实例是否属于某个类
  3. constructor 构造函数
  4. Object.prototype.toString.call() 原型链上的Object对象的toString方法

下面我们就来分别介绍一下上面四种方法的适用场景和局限性。

  • 1.typeof 用来检测数据类型的运算符

使用typeof检测数据类型,返回值是字符串格式。能够返回的数据类型有6种

是:"number","string","bolean","undefined","function","object"。

<script>
 console.log(typeof(1)); //number
 console.log(typeof('hello')); //string
 console.log(typeof(true)); //boolean
 console.log(typeof(undefined)); //undefined
 console.log(typeof(null)); //object
 console.log(typeof({})); //object
 console.log(typeof(function() {})); //function
</script>

局限性:

typeof (null); //"object"。这是由于在js中,null值表示一个空对象指针,而这也正是使用typeof操作 符检测null值时会返回"object"的原因(笔试面试常考)

不能具体的细分是数组还是正则,还是对象中其他的值,因为使用typeof检测数据类型,对于对象数据类型的所有的值,最后返回的都是"object"

  • 2.instanceof 检测某一个实例是否属于某个类

instanceof主要用来弥补typeof不能检测具体属于哪个对象的局限性。

<script>
 let arr = [1,2,3];
 let reg = /\w/;
 console.log(arr instanceof Array); //true
 console.log(arr instanceof Object); //true
 console.log(reg instanceof RegExp); //true
 console.log(reg instanceof Object); //true
</script>

局限性:

不能用于检测和处理字面量方式创建出来的基本数据类型值,即原始数据类型

instanceof的特性:只要在当前实例的原型链上的对象,我们用其检测出来都为true

在类的原型继承中,我们最后检测出来的结果未必正确

  • 3.constructor 构造函数

是函数原型上的属性,该属性指向的是构造函数本身。

作用和instsnceof非常相似,与instanceof不同的是,不仅可以处理引用数据类型,还可以处理原始数据类型。

<script>
 let num = 12;
 let obj = {};
 console.log(num.constructor == Number);//true
 console.log(obj.constructor == Object);//true
</script>

但是要注意一点的是,当直接用(对象字面量或原始数据).constructor时,最好加上()。为了便于理解,我们来看一个例子。

<script>
 1.constructor === Number; //报错,Invalid or unexceped token
 (1).constructor === Number; //true
 {}.constructor === Number; //报错,Invalid or unexceped token
 ({}).constructor === Number; //true
</script>

这主要是由于js内部解析方式造成的,js会把1.constructor解析成小数,这显然是不合理的,小数点后应该是数字,因此就会引发报错。js会把{}解析成语句块来执行,这时后面出现一个小数点显然也是不合理的,因此也会报错。为了解决这个问题,我们可以为表达式加上()使js能够正确解析。

局限性:我们可以把类的原型进行重写,在重写的过程中很可能把之前constructor给覆盖了,这样检测出来的结果就是不准确的

<script>
 function Fn() {};
 Fn.prototype = new Array;
 var f = new Fn;
 //f是一个函数,按道理说他的构造函数应该是Function,但是修改其原型链后,它的constructor变成了Array.
 console.log(f.constructor == Array); //true
</script>
  • 4.Object.prototype.toString.call() 原型链上的Object对象的toString方法

Object.prototype.toString的作用是返回当前方法的执行主体(方法中的this)所属类的详细信息,是最全面也是最常用的检测数据类型的方式。

返回值的类型为string类型。

<script> 
 console.log(Object.prototype.toString.call(1)); //[object Number]
 console.log(Object.prototype.toString.call(/^sf/)); //[object RegExp]
 console.log(Object.prototype.toString.call("hello")); //[object String]
 console.log(Object.prototype.toString.call(true)); //[object Boolean]
 console.log(Object.prototype.toString.call(null)); //[object Null]
 console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
 console.log(Object.prototype.toString.call(function() {})); //[object Function]
 console.log(typeof(Object.prototype.toString.call(function() {}))); //string
</script>

二、数据类型

栈 :栈,只允许在一段进行插入或者删除操作的线性表,是一种先进后出的数据结构。

堆 :堆是基于散列算法的数据结构。

队列:队列是一种先进先出(FIFO)的数据结构。

JavaScript中将数据类型分为基本数据类型和引用数据类型,它们其中有一个区别就是存储的位置不同。

  • a.我们都知道JavaScript中的基本数据类型有:
String
Number
Boolean
Undefined
Null
Symbol(暂时不管)

基本数据类型都是一些简单的数据段,它们是存储在栈内存中。

  • b.JavaScript中的引用数据类型有:
Array
Object

引用数据类型是保存在堆内存中的,然后再栈内存中保存一个对堆内存中实际对象的引用。所以,JavaScript中对引用数据类型的操作都是操作对象的引用而不是实际的对象。

可以理解为,栈内存中保存了一个地址,这个地址和堆内存中的实际值是相关的。

  • c.图解 (可以通过下图来表示数据类型在内存中的存储情况):
var name="axuebin";
var age=25;
var job;
var arr=[1,2,3];
var obj={age:25};

此时name,age,job三种基本数据类型是直接存在栈内存中的,而arr,obj在栈内存中只是存了一个地址来表示对堆内存中的引用。

  • d.复制

基本数据类型

对于基本数据类型,如果进行复制,系统会自动为新的变量在栈内存中分配一个新值,很容易理解。

引用数据类型

如果对于数组、对象这样的引用数据类型而言,复制的时候就会有所区别了:

系统也会自动为新的变量在栈内存中分配一个值,但这个值仅仅是一个地址。也就是说,复制出来的变量和原有的变量具有相同的地址值,指向堆内存中的同一个对象。

当我修改obj或objCopy时,都会引起另一个变量的改变。

参考文章

https://m.jb51.net/article/145078.htm

https://m.jb51.net/article/135920.htm

最近发表
标签列表