zoukankan      html  css  js  c++  java
  • JavaScript 数据类型小结

    数据类型对于机器而言,其意义在于更加合理的分配内存空间,而对于编程者而言,数据类型提供了我们相对应的一系列方法,对数据进行分析与处理。

    在本文中,将对JavaScript数据类型的基础知识进行总结,全文分为四个部分:

    1. 数据类型分类
    2. 各数据类型的值与含义
    3. 类型判断
    4. 类型转换

    一 数据类型分类

    JavaScript有六种数据类型,分别是:string,number,boolean,null,undefind和object,根数据的存储方式又可以将六种数据类型分类为简单(基本)类型和复杂(引用)类型两类,其中前五个归为简单(基本)类型,只有object归类为复杂(引用)类型。

    之所以这样分类的原因在于,简单(基本)类型使用栈内存,其结构为“变量名:值”的对应关系,因此在复制变量时,复制的是变量所指向的具体值,因此对复制对象值的改动不会改变被复制对象的值;而复杂(引用)类型则使用了堆内存,其结构为“变量名:指针”的对应关系,由“指针”再指向一堆“名:值”对应的值堆,因此当复制一个复杂(引用)类型的值时,复制的其实是一个指向名值堆得“指针”,因此对任何名值堆内值的改动都会反映到所有复制对象上。

    此处有配图,一图胜千言。

    除此之外,复杂(引用)类型又可以根据其性质分为原生对象,宿主对象和自定义对象三大类,因此整个JavaScript数据类型的分类最终如图1-2所示:

    图1-2

    二 各数据类型的值与含义

    1. string类型 代表字符串 值:引号包围的字符串
    2. number类型 代表数字,可以使整数,或浮点数 值:数字,NaN
    3. boolean类型 代表真/假的状态 值:关键字true,false
    4. undefined类型 代表一个未定义的值 值:undefined 
    5. null类型 代表有一个值,但值为空
    6. object类型 代表无须的键值对的集合 值:{}包围的无序键值对集合

    三 类型判断

    通过预先判断JavaScript的数据类型,我们可以选择对应的方法对数据进行处理,使其符合我们的功能需求。JavaScript的类型判断方法有四种,下面进行一一介绍。

    (1)typeof 运算符

    typeof运算符的用法为:  

    typeof 100; //number

    其用法十分好懂,即运算符+被检验值,可以得出被检验值的数据类型。

    但是遗憾的是,typeof检验数据类型有其缺陷,即typeof只能检验JavaScript的6种数据类型,其中null的检验结果还是错的,为object。

    因此,使用typeof只能检验出数据是否为string,number,boolean,undefined或object(可能是object或null),无法检验出数据具体的对象类型,此时又出现一个意外,function对象类型可以被检测出来。

    (2)instanceof 运算符

    instanceof运算符的用法为:

    [] instanceof Array; //true

    可以看到instanceof运算符的使用就不如typeof那么简便了,这好像你必须先预先对数据的类型进行判断,然后instanceof只告诉你你的判断是错了还是对了。

    同样的,instanceof仍然有他的缺陷,即instanceof是无法判别简单(基本)类型的数据的,如下例:

    1 instanceof Number; //false

    这是因为1为简单(基本)类型,他只有调用Number方法时才暂时转换为Number对象类型,当方法调用完毕时又会立即转换为简单(基本)类型。

    除了这个小小的缺陷外,instanceof是可以判断出所有的对象类型的,这甚至包括了你自定义的对象类型。

    (3)Object.prototype.toString.call方法

    这个方法可以分为两步,第一步为调用Object.prototype.toString方法,第二步为调用call方法,下面依次讲解这两步都做了些什么。

    1.Object.prototype.toString方法在ES5中的规范如下:

    当toString方法被调用时,执行以下操作

    1. 获取this对象的[[Class]]属性的值
    2. 如果this的值为null,则返回“[object Null]”
    3. 如果this的值为undefined,则返回“[object Undefined]”
    4. 计算出三个字符串"[object", 第一步操作的结果,"]",并连接字符串
    5. 返回第4步生成的新字符串

    简而言之此方法能够读取this对象的[[Class]]属性,并将其与固定字符串拼接成为一个新字符串再返回。

    那么这个[[Class]]属性又是什么呢?

    根据规范,[[Class]]属性是一个内部属性,所有对象(原生对象和宿主对象)都拥有该属性,他是一个字符串值,表明了该对象的类型。注意,这个内部属性只能被toString方法读取。

    那么这下,这个方法的功能就一目了然了。

    2.call()方法

    call()方法的作用为改变函数内部this的指向,并向函数提供参数。因此通过两个方法的结合,就很容易通过Object.prototype.toString.call方法判断出标准类型与内置对象类型,但是缺陷在于,此方法不能识别自定义对象类型。

    为了简便,我们还可以封装此方法为一个函数:

    function type(obj) {
        return Object.prototype.toString.call(obj).slice(8,-1);      
    }

    (4)constructor属性

    constructor为生成这个对象的构造函数本身,利用这个特点,可以使用constructor判别标准类型(undefinded和null除外),内置对象类型和自定义对象类型。

    "jenny".constructor === String; //true
    
    [].constructor === Array; //true
    
    function Person(name) {
        this.name = name;
    }
    new Person("jenny").constructor === Person; //true

    值得一提的是,之所以字符串"jenny"可以使用constructor方法获得其构造函数,是因为当简单(基本)类型使用点操作符时,会先自动转换为其对应构造函数,因此可以凭此取得其数据类型,而由于undefined与null没有相对应的构造函数,因此无法通过此方法进行判别。

    我们也可以对此方法进行封装:

     

    function getConstructorName(obj) {
        return obj && obj.constructor && obj.constructor.toString().match(/functions*([^(]*)/)[1];
    }

     至此,类型判断的四种方法就小结结束了,在使用的过程中,需要根据具体的情况酌情使用不同的类型判断方法,例如

    1. 仅需判断数据是简单基本类型的哪一种 使用typeof运算符
    2. 需要判断具体对象类型,包括内置对象类型和自定义对象类型 结合typeof运算符,使用instanceof运算符(需要提供可能的类型对象以返回true或false)
    3. 不需要判断自定义对象类型,但需要判断简单基本类型和内置对象类型 使用Object.prototype.toString.call方法
    4. 除了undefined和null外,判断所有对象类型 使用constructor属性

    四 类型转换

     JavaScript的数据类型转换分为显式类型转换与隐式类型转换两种,下面分别进行总结:

    (1)显式类型转换

    显示类型转换的一些方法如下:

    1. 字符串转换为数字  Number()方法
    2. 数字转换为字符串 String()方法
    3. 参数对象转换为布尔值  Boolean()方法
    4. 将字符串转换为整型或浮点数数字  parseInt(),parseFloat()方法
    5. 将对象转换为布尔值  !,!!运算符

    (2)隐式类型转换

    在以下四个场景下,会进行隐式类型转换:

    1.  数字运算符
    2. "." 操作符
    3. if语句中
    4. == 操作符

    转换结果如图:

  • 相关阅读:
    matcaffe的blob维度顺序
    ftp同步代码
    SpringCloud的微服务网关:zuul(实践)
    SpringCloud的微服务网关:zuul(理论)
    SpringCloud的服务消费者 (二):(rest+feign/ribbon)声明式访问注册的微服务
    SpringCloud的服务消费者 (一):(rest+ribbon)访问注册的微服务
    SpringCloud的服务注册中心(二)注册中心服务端和两个微服务应用客户端
    Jetty入门(1-3)Eclipse集成gradle-Gretty插件或maven-jetty插件运行应用
    HTTP协议扫盲(三)HTTP协议的请求头列表和分类描述
    Jetty入门(1-2)eclipse集成jetty插件并发布运行应用
  • 原文地址:https://www.cnblogs.com/libinfs/p/5749472.html
Copyright © 2011-2022 走看看