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

基本数据类型

1.基本数据类型的值是不可变的。

var str = "abc";
str[0] = "d"; // 字符串是可以通过[]访问的

console.log(str[1]="e"); // e
console.log(str[0]); // a
console.log(str); // abc

在JavaScirpt中,数字、字符串、布尔值、Null和Undefined的值是不可改变的,就算在代码中动态地修改它的值,它的原始值并不会发生改变,如果需要修改值,都是通过定义一个变量来保存这个新值,因为它的返回值就是修改后的值。

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

3.值的比较可以用【==】或【===】运算符。【==】只进行值的比较,【===】不仅进行值的比较,还要进行数据类型的比较。

var num = 1; // Number类型
var str = "1"; // String类型 console.log(num == str); // true,只比较值
console.log(num === str); // false,不仅比较值,还比较数据类型

引用数据类型

1.引用数据类型的值是可变的。

var num = [1,2,3];
num[0] = "a";

console.log(num); // ["a", 2, 3]

在JavaScript中,数组和对象的值是可变的,也就是说当动态修改里面的值的时候,原始的值也会发生相应的改变。

2.引用数据类型同时保存在栈内存和堆内存。

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

3.引用数据类型比较的是引用地址。当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量上的对象的值赋值一份放到为新变量分配的空间中。

var obj1 = {age: 22};
var obj2 = obj1; // 将obj1赋值给obj2,实际上是将obj1指向的内存地址赋值给obj2 console.log(obj1 === obj2); // true,obj1和obj2指向同一块内存空间 obj2.age = 18; // obj2修改属性的同时,obj1也一起发生了改变,因为它们指向同一个对象,任何修改操作都会相互影响
console.log(obj1 === obj2); // true,obj1和obj2还是指向同一块内存空间

数据类型的检测

在JavaScript中,要检测一个变量的数据类型,主要有5种方法。

1.【typeof】运算符

【typeof】返回一个表示数据类型的字符串,返回结果包括7种:"number"、"boolean"、"string"、"symbol"、"object"、"undefined"、"function"。

typeof Symbol(); // symbol 有效
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; // boolean 有效
typeof undefined; // undefined 有效
typeof new Function(); // function 有效
typeof null; // object 无效
typeof []; // object 无效
typeof new Date(); // object 无效
typeof new RegExp(); // object 无效

使用【typeof】运算符时,对于数组和对象,返回的都是"object",没有什么卵用。因此【typeof】主要是用来判断基本数据类型的,当然了,除了Null。那么这时就到【instanceof】运算符上场了。

2.【instanceof】运算符

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

[] instanceof Array; // true
{} instanceof Object; // true
new Date() instanceof Date; // true
new RegExp() instanceof RegExp; // true

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

console.log(1 instanceof Number); // false
console.log(new Number(1) instanceof Number); // true

从严格意义上来讲,只有实例创建出来的对象才是标准的对象数据类型值,也是标准的Number这个类的一个实例;对于字面量创建出来的结果是基本的数据类型值,不是严谨的实例,但是由于JavaScript的松散特点,导致了可以使用Number.prototype上提供的方法。只要在当前实例的原型链上,我们用其检测出来的结果都是true。在类的原型继承中,我们最后检测出来的结果未必是准确的(坑爹)。

var arr = [1, 2, 3];
function fn(){} console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true
console.log(fn instanceof Function); // true
console.log(fn instanceof Object); // true

另外,【instanceof】运算符也不能用来检测null和undefined。对于这两种特殊的数据类型,对应的类是Null和Undefined,浏览器把这两个类保护起来了,不允许访问使用。

而对于数组的类型判断,其实还可以用ES6新增的Array.isArray()。

Array.isArray([]);  // true

3.【===】严格运算符

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

var a = null;
var b; console.log(typeof a); // "object"
console.log(typeof b); // "undefined"
console.log(a === null); // true
console.log(b === undefined); // true

4.【constructor】属性

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

var arr = [1,2];
var reg = /^$/; // 正则表达式 console.log(arr.constructor === Array); // true
console.log(arr.constructor === RegExp); // false
console.log((1).constructor === Number); // true
console.log(reg.constructor === RegExp); // true
console.log(reg.constructor === Object); // false

因为null和undefined是无效的对象,因此是不会有constructor存在的,这两种类型的数据需要通过其它方式判断,比如上面的【===】严格运算符。

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

function Fn(){}
Fn.prototype = new Array();
var f = new Fn;

console.log(f.constructor); // Array

5.【Object.prototype.toString.call()】函数

【Object.prototype.toString.call()】是最准确、最常用的方式。首先获取Object原型上的toString()方法,让方法执行,然后让toString()方法中的this指向第一个参数的值。为什么要这样写而不是用对象直接调用toString()方法,是因为每个类重写了toString()方法,而实际要调用的是Object的原型方法toString(),不理解的话建议去看看原型链继承相关的知识。

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

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(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(new RegExp()); // [object RegExp]
Object.prototype.toString.call(new Error()); // [object Error]
Object.prototype.toString.call(document); // [object HTMLDocument]
Object.prototype.toString.call(window); //[object global] window是全局对象global的引用

关于toString的重要补充:toString的本意是转换为字符串,一般用来将值转换为字符串。但是对于Number、String、Boolean、Array、RegExp、Date、Function原型上的toString属性(值是函数),都是用于把当前的数据类型转换为字符串,Object上的toString也是同样的,返回的是数据类型的字符串,而不是值的字符串。

"这世上没有平白无故的闪闪发光。"

javascript的数据类型检测的更多相关文章

  1. JavaScript系列文章:不能不看的数据类型检测

    由于JavaScript是门松散类型语言,定义变量时没有类型标识信息,并且在运行期可以动态更改其类型,所以一个变量的类型在运行期是不可预测的,因此,数据类型检测在开发当中就成为一个必须要了解和掌握的知 ...

  2. JS-安全检测JavaScript基本数据类型和内置对象的方法

    前言:在前端开发中经常会需要用到检测变量数据类型的需求,比如:判断一个变量是否为undefined或者null来进行下一步的操作,今天在阅读“编写高质量代码-改善JavaScript程序的188个建议 ...

  3. javascript 数据类型 -- 检测

    一.前言 在上一篇博文中 Javascript 数据类型 -- 分类 中,我们梳理了 javascript 的基本类型和引用类型,并提到了一些冷知识.大概的知识框架如下: 这篇博文就讲一下在写代码的过 ...

  4. JavaScript 数据类型检测总结

    JavaScript 数据类型检测总结 原文:https://blog.csdn.net/q3254421/article/details/85483462 在js中,有四种用于检测数据类型的方式,分 ...

  5. JavaScript: 数据类型检测

    由于JavaScript是门松散类型语言,定义变量时没有类型标识信息,并且在运行期可以动态更改其类型,所以一个变量的类型在运行期是不可预测的,因此,数据类型检测在开发当中就成为一个必须要了解和掌握的知 ...

  6. 【JavaScript框架封装】数据类型检测模块功能封装

    数据类型检测封装后的最终模块代码如下: /*数据类型检验*/ xframe.extend(xframe, { // 鸭子类型(duck typing)如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭 ...

  7. JS中的数据类型检测

    JavaScript的数据类型分为两类:原始类型(primitive type)和对象类型(object type).原始类型有5种,分别是:数字(Number).字符串(String).布尔值(Bo ...

  8. JavaScript 学习之第一篇JavaScript的数据类型(2016/8/29 晚 23:12)

    1. JavaScript的数据类型 JavaScript 里面有6中数据类型 Boolean String Number Undefined Null Object object(对象)类型包含了数 ...

  9. 从头开始学JavaScript (三)——数据类型

    原文:从头开始学JavaScript (三)--数据类型 一.分类 基本数据类型:undefined.null.string.Boolean.number 复杂数据类型:object object的属 ...

随机推荐

  1. Python - 部分PEP8规范

    写代码就像写字一样,为什么有的人写的字十分漂亮,而有的人写的字过后连自己都不认识,最主要还是从一开始是否对自己严格要求.从现在开始就当自己是个初学者,把代码写漂亮点.以下截取了部分PEP8代码规范,里 ...

  2. mysql Hash索引和BTree索引区别

    Hash仅支持=.>.>=.<.<=.between.BTree可以支持like模糊查询 索引是帮助mysql获取数据的数据结构.最常见的索引是Btree索引和Hash索引. ...

  3. git基本操作:分支管理

    一.创建测试项目 1.新建GitHub仓库 在GitHub上面新创建一个仓库,用来演示分支管理,如下图所示: 点击“Create repository”按钮创建新仓库. 2.将本地仓库项目上传到Git ...

  4. Python爬取上交所一年大盘数据

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 半个码农2018 PS:如有需要Python学习资料的小伙伴可以加点 ...

  5. Redis中使用redis-cli及密码登录

    使用redis-cli登录后如果Redis中设置了密码那么输入密码可能会出现: NOAUTH Authentication required的错. 这个时候可以输入:auth password 进行登 ...

  6. MySQL 部署分布式架构 MyCAT (二)

    安装 MyCAT 安装 java 环境(db1) yum install -y java 下载 Mycat-server-1.6.5-release-20180122220033-linux.tar. ...

  7. [视频教程] redis中的bit运用统计用户在线天数

    位运算在redis中非常的方便使用,并且理由利用这个可以实现很多特殊的功能.这也迫使我去研究更多的redis提供的函数,只有研究的多,思路才能够更加开放.今天我就对strings下面的几个函数进行了测 ...

  8. 关于如何清除某个特定网站的缓存---基于Chrome浏览器

    1.清除浏览器缓存 直接在浏览器设置里面清除浏览器的缓存会清除所有网站的缓存信息,这在某些时候是非常不方便的,毕竟不只有测试网站,还会有一些我们不想清除的信息也会被清除掉: 2.通过F12功能去清除浏 ...

  9. jsp页面格式化时间 fmt:formatDate格式化日期

    使用fmt函数需在jsp中引入 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" ...

  10. python使用face_recognition包的环境设置

    在使用face_recognition包进行人脸识别时,环境是非常重要的,但是网上办法特别纷杂,今天介绍一种特别简单的办法,希望能帮助到大家,少走些坑. 1.首先应该下载dlib安装包(例如:dlib ...