原标题:JavaScript 的数据类型及其检测

作者:浪里行舟

Java 有几种类型的值?

Java 有两种数据类型,分别是基本数据类型和引用数据类型。其中基本数据类型包括 Undefined、Null、Boolean、Number、String、Symbol (ES6 新增,表示独一无二的值),而引用数据类型统称为 Object 对象,主要包括对象、数组和函数。接下来我们分别看下两者的特点。

基本数据类型

1.值是不可变的

varname= 'java';

name.toUpperCase(); // 输出 'JAVA'

console.log(name); // 输出 'java'

由此可得,基本数据类型的值是不可改变的

2.存放在栈区

原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储。

3.值的比较

vara = 1;

varb = true;

console.log(a == b); // true

console.log(a === b); // false

== : 只进行值的比较,会进行数据类型的转换。

=== : 不仅进行值得比较,还要进行数据类型的比较。

引用数据类型

1.值是可变的

vara={ age: 20};

a.age= 21;

console.log(a.age) //21

上面代码说明引用类型可以拥有属性和方法,并且是可以动态改变的。

2.同时保存在栈内存和堆内存

引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

3.比较是引用的比较

当从一个变量向另一个变量赋引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。

vara={ age: 20};

varb=a;

b.age= 21;

console.log(a.age==b.age) //true

上面我们讲到基本类型和引用类型存储于内存的位置不同,引用类型存储在堆中的对象,与此同时,在栈中存储了指针,而这个指针指向正是堆中实体的起始位置。变量 a 初始化时,a 指针指向对象{age:20}的地址,a 赋值给 b 后,b 又指向该对象{age:20}的地址,这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响。

此时,如果取消某一个变量对于原对象的引用,不会影响到另一个变量。

vara={age: 20};

varb=a;

a = 1;

b // {age:20}

上面代码中,a 和 b 指向同一个对象,然后 a 的值变为 1,这时不会对 b 产生影响,b 还是指向原来的那个对象。

检验数据类型

1.typeof

typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、symbol、object、undefined、function 等 7 种数据类型,但不能判断 null、array 等

typeofSymbol(); // symbol 有效

typeof''; // string 有效

typeof1; // number 有效

typeoftrue; //boolean 有效

typeofundefined; //undefined 有效

typeofnewFunction(); // function 有效

typeofnull; //object 无效

typeof[] ; //object 无效

typeofnewDate(); //object 无效

typeofnewRegExp(); //object 无效

数组和对象返回的都是 object,这时就需要使用 instanceof 来判断

2.instanceof

instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

[] instanceofArray; //true

{} instanceofObject; //true

newDate() instanceofDate; //true

newRegExp() instanceofRegExp//true

关于数组的类型判断,还可以用 ES6 新增Array.isArray()

Array.isArray([]); // true

instanceof 三大弊端:

对于基本数据类型来说,字面量方式创建出来的结果和实例方式创建的是有一定的区别的

console.log( 1instanceofNumber) //false

console.log( newNumber( 1) instanceofNumber) //true

从严格意义上来讲,只有实例创建出来的结果才是标准的对象数据类型值,也是标准的 Number 这个类的一个实例;对于字面量方式创建出来的结果是基本的数据类型值,不是严谨的实例,但是由于 JS 的松散特点,导致了可以使用 Number.prototype 上提供的方法。

只要在当前实例的原型链上,我们用其检测出来的结果都是 true。在类的原型继承中,我们最后检测出来的结果未必准确。

vararr = [ 1, 2, 3];

console.log(arr instanceofArray) // true

console.log(arr instanceofObject); // true

functionfn(){}

console.log(fn instanceofFunction) // true

console.log(fn instanceofObject) // true

不能检测 null 和 undefined

对于特殊的数据类型 null 和 undefined,他们的所属类是 Null 和 Undefined,但是浏览器把这两个类保护起来了,不允许我们在外面访问使用。

3.严格运算符===

只能用于判断 null 和 undefined,因为这两种类型的值都是唯一的。

vara = null

typeofa // "object"

a === null// true

undefined 还可以用 typeof 来判断

varb = undefined;

typeofb === "undefined"// true

b === undefined// true

4.constructor

constructor 作用和 instanceof 非常相似。但 constructor 检测 Object 与 instanceof 不一样,还可以处理基本数据类型的检测。

varaa=[ 1, 2];

console.log(aa.constructor=== Array); //true

console.log(aa.constructor=== RegExp); //false

console.log(( 1).constructor=== Number); //true

varreg= /^$/;

console.log(reg.constructor=== RegExp); //true

console.log(reg.constructor=== Object); //false

constructor 两大弊端:

null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

函数的 constructor 是不稳定的,这个主要体现在把类的原型进行重写,在重写的过程中很有可能出现把之前的 constructor 给覆盖了,这样检测出来的结果就是不准确的

functionFn(){}

Fn.prototype = newArray()

varf = newFn

console.log(f.constructor) //Array

5.Object.prototype.toString.call()

Object.prototype.toString.call() 最准确最常用的方式。首先获取 Object 原型上的 toString 方法,让方法执行,让 toString 方法中的 this 指向第一个参数的值。

关于 toString 重要补充说明:

本意是转换为字符串,但是某些 toString 方法不仅仅是转换为字符串

对于 Number、String,Boolean,Array,RegExp、Date、Function 原型上的 toString 方法都是把当前的数据类型转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)

Object 上的 toString 并不是用来转换为字符串的。

Object 上的 toString 它的作用是返回当前方法执行的主体(方法中的 this)所属类的详细信息即"[object Object]",其中第一个 object 代表当前实例是对象数据类型的(这个是固定死的),第二个 Object 代表的是 this 所属的类是 Object。

Object.prototype.toString.call( '') ; // [object String]

Object.prototype.toString.call( 1) ; // [object Number]

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( newFunction()) ; // [object Function]

Object.prototype.toString.call( newDate()) ; // [object Date]

Object.prototype.toString.call([]) ; // [object Array]

Object.prototype.toString.call( newRegExp()) ; // [object RegExp]

Object.prototype.toString.call( newError()) ; // [object Error]

Object.prototype.toString.call( document) ; // [object HTMLDocument]

Object.prototype.toString.call( window) ; //[object global] window是全局对象global的引用

参考资料

【文章】[ JS 进阶 ] 基本类型 引用类型 简单赋值 对象引用(推荐)

JS 判断数据类型的三种方法

JS 中的数据类型及判断

Java 判断变量类型的陷阱 与 正确的处理方式

判断 JS 数据类型的四种方法

【本文作者】

浪里行舟:硕士研究生,专注于前端,立志成为全栈工程师。乐于分享,坚持输出,愿文章能够给你带来点启发!返回搜狐,查看更多

责任编辑:

java 获取js变量类型_JavaScript 的数据类型及其检测相关推荐

  1. java intf判断变量类型_Java 的数据类型

    数据类型 概要 Java是一种强类型语言,每个变量都必须声明其类型. Java的数据类型分为两大类:基本类型(primitive type)和引用类型 (reference type) Java中定义 ...

  2. eclipse中java获取js的值_javascript – 如何在Eclipse中使用Selenium将外部.js导入我的Java测试?...

    It works, but it's not very useful, because I want to make an external .js which contains all the Ja ...

  3. 第一记: JS变量类型判断(VUE源码解读)

    学习摘要 : 以前总是对js变量类型的判断模糊不清楚,今天看到vue源码后才恍然大悟原来大神都是这样弄的,所以加以总结,写的不好的请大神们多多吐槽吐槽!!!!!! Vue 源码 /* 获取值的原始类型 ...

  4. Java中,一切皆是对象——java中的对象类型与基本数据类型的区别

    起因:取一个list给另一个list赋值,然后在另一个list中取出进行修改.list其中类型为对象时,String时,基本数据类型时. [java中的对象类型与基本数据类型的区别] #声明和实例化 ...

  5. php 获取js变量

    2019独角兽企业重金招聘Python工程师标准>>> 1.新建一个测试文件,如test.php 2.把如下代码: //php 获取js变量 <script>var aa ...

  6. 【java】java获取对象属性类型、属性名称、属性值

    java获取对象属性类型.属性名称.属性值 获取属性 修饰符:[在Field[]循环中使用] String modifier = Modifier.toString(fields[i].getModi ...

  7. C#-获取某变量类型的默认值

    简单的获取某变量类型的默认值 在c#中为我们提供了default().我在记录的是另一种获取变量类型的Type的默认值Code如下: 1 public static object DefaultFor ...

  8. java 获取系统变量(环境变量和设置变量)

    前言 环境变量这个概念不陌生, 就是操作系统的环境变量. 系统变量就是java本身维护的变量. 通过 System.getProperty 的方式获取. 对于不同的操作系统来说, 环境变量的处理可能会 ...

  9. JS变量的定义和数据类型

    JavaScript 输出 JavaScript 没有任何打印或者输出的函数. JavaScript 可以通过不同的方式来输出数据: 使用 window.alert() 弹出警告框. 使用 docum ...

最新文章

  1. 重塑HPE:6笔收购推动销售增长
  2. 当final作用于变量、参数、方法和类时该如何处理
  3. EasyExcel读取文件异常,报 java.lang.NoClassDefFoundError,/x2006/main/CTTableStyles
  4. linux iso合并,把RedHat Linux 5.0的CD ISO合并成DVD的脚本
  5. mysql 查看表格scott_mysql查询学习第一天,针对scott
  6. 洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)
  7. JS实现鼠标点击展开/隐藏表格行
  8. linux网站权限一直自动关闭,奇妙伞-解决SELinux对网站目录权限控制的不当的问题--网上摘抄集合,记录使用...
  9. NLP简报(Issue#4):Turing-NLG、REALM、ERNIE-GEN、Transformer attention可视化等等
  10. 2021年C++项目中的十大Bug:乍一看都正确的代码,实则暗藏玄机
  11. 【MySQL】语句抓包分析工具MySQL sniffer
  12. python 弹出窗口闪烁_游戏窗口闪烁
  13. 赛门铁克分家前利润暴跌
  14. 机器学习(周志华)知识点总结——第2章 模型评估与选择(后期上传word/PDF)
  15. 聊聊mac系统的 secoclient和iTerm2
  16. 秒级去重:ClickHouse在腾讯海量游戏营销活动分析中的应用
  17. 淘宝API 添加上传商品图片
  18. 火焰识别python_五行属火的字大全
  19. 微信PC端C++技术获取聊天内容,这个技术足以进入腾讯上班!
  20. java实现美图秀秀的照片拼接功能(照片数量任意)

热门文章

  1. (转)The Standard C Library 经典的基础(下)
  2. istio多集群链路追踪,附实操视频
  3. 作业,输入名字密码,按dict插入到list,非法字符显示*
  4. thinkphp命名空间
  5. 爱立信牵手微软,加速物联网全球生态
  6. thinkjs——两表联查
  7. Git忽略文件或文件夹
  8. MongoDB初探系列之二:认识MongoDB提供的一些经常使用工具
  9. 阿里云主机CentOS添加硬盘
  10. 软件设计师1991下午试题1(流程图解析)