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. C# 异或

    遗忘的东西. 真的是很少用呀. 操作符为^ 简单来说就是相同为假(0),不同为真(1). 给一个小小的例子(密文) class Program { static void Main(string[] ...

  2. this泛指函数的上下文

    this泛指函数的上下文 当前函数运行的类型上下文.

  3. 在dubbo的一端,看Netty处理数据包,揭网络传输原理

    如今,我们想要开发一个网络应用,那是相当地方便.不过就是引入一个框架,然后设置些参数,然后写写业务代码就搞定了. 写业务代码自然很重要,但是你知道: 你的数据是怎么来的吗?通过网络传输过来的呗. 你知 ...

  4. ASP.NET Core框架深度学习(二) 管道对象

    4.HttpContext 第一个对象 我们的ASP.NET Core Mini由7个核心对象构建而成.第一个就是大家非常熟悉的HttpContext对象,它可以说是ASP.NET Core应用开发中 ...

  5. Java的23种设计模式,详细讲解(一)

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  6. python 通过使用pandas的实现的Excel的批量转换CSV文件的处理

    ---恢复内容开始--- 最近同事在处理文件导入的时候需要把一批文件换成CSV的格式,但是直觉修改后缀是不生效的,而且xlsx和xls的文件没法直接换成CVS的文件,所以找了一下方式,并且自己实现了p ...

  7. 【面试突击】-RabbitMQ常见面试题(三)

    1.什么是RabbitMQ?为什么使用RabbitMQ? 答:RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的,消息中间件: 可以用它来:解耦.异步.削峰. 2.RabbitMQ有 ...

  8. 表单_HTML

    HTML表单_输入元素 大多数情况被用到的表单标签是输入标签 输入类型是由类型属性(type)定义的. 表单中的单选按钮可以设置以下几个属性:value.name.checked value:提交数据 ...

  9. TypeScript 学习笔记(三)

    类: 1.TypeScript 是面向对象的 JavaScript,类描述了创建的对象共同的属性和方法 2.类通过关键字 class 声明,使用 extends 关键字进行继承 3.在引用一个类成员时 ...

  10. yum / rpm 指令无反应

    当yum 或者 rpm 指令执行后没有任何反馈,可尝试执行以下指令: # rm -f /var/lib/rpm/__db.00* # 删除rpm数据文件 # rpm –rebuilddb # 重建rp ...