美文网首页
JS数据类型和转换

JS数据类型和转换

作者: 莫藤苔 | 来源:发表于2018-08-31 00:02 被阅读0次

    一、初识数据类型

    1. 概要

    JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有七种。

    数值(number):整数和小数(比如1和3.14);

    字符串(string):文本(比如Hello World);

    布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假);

    undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值;

    null:表示空值,即此处的值为空;

    对象(object):各种值组成的集合;

    Symbol类型 :不介绍。

    对象是最复杂的数据类型,又可以分成三个子类型。

    狭义的对象(object)

    数组(array)

    函数(function)

    2. typeof 运算符

    由于ECMAScript是松散型,JavaScript 有三种方法,可以确定一个值到底是什么类型。

    typeof运算符;

    instanceof运算符;

    Object.prototype.toString方法。

    用typeof检测变量可能返回以下某个字符串。

    image

    null开始为Object类型的一个数据,后来独立为一种数据类型,为了兼容以前的代码,typeof null返回object就没法改变了。


    二、数据类型详解

    1. null 和 undefined

    1.1 概述

    null表示‘空值’,undefined表示‘未定义’。

    1.2 用法和含义

    null表示‘空值’,调用函数时,某个参数未设置任何值,这时就可以传入null,表示该参数为空。比如,某个函数接受引擎抛出的错误作为参数,如果运行过程中未出错,那么这个参数就会传入null,表示未发生错误。

    undefined表示“未定义”,下面是返回undefined的典型场景。

    // 变量声明了,但没有赋值
    var i;
    i // undefined
    
    // 调用函数时,应该提供的参数没有提供,该参数等于 undefined
    function f(x) {
      return x;
    }
    f() // undefined
    
    // 对象没有赋值的属性
    var  o = new Object();
    o.p // undefined
    
    // 函数没有返回值时,默认返回 undefined
    function f() {}
    f() // undefined
    

    2. 布尔值

    布尔值代表“真”和“假”两个状态。“真”用关键字true表示,“假”用关键字false表示。

    3. 数值

    3.1 概述

    i. 浮点数

    JavaScript 语言的底层没有整数,所有数字都是以64位浮点数形式储存;所以,1与1.0是同一个数;某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算。

    由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。

    0.1 + 0.2 === 0.3
    // false
    
    0.3 / 0.1
    // 2.9999999999999996
    
    (0.3 - 0.2) === (0.2 - 0.1)
    // false
    

    ii. 数值精度

    根据国际标准 IEEE 754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

    第1位:符号位,0表示正数,1表示负数;

    第2位到第12位(共11位):指数部分;

    第13位到第64位(共52位):小数部分(即有效数字)。

    简单的法则就是,JavaScript 对15位的十进制数都可以精确处理。

    iii. 数值范围

    JavaScript 能够表示的数值范围为(21024,2-1023),超出这个范围的数无法表示。

    如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回Infinity。

    如果一个数小于等于2的-1075次方(指数部分最小值-1023,再加上小数部分的52位),那么就会发生为“负向溢出”,即 JavaScript 无法表示这么小的数,这时会直接返回0。

    var x = 0.5;
    
    for(var i = 0; i < 25; i++) {
      x = x * x;
    }
    
    x // 0
    

    3.2 普通数值

    i. 普通数值的表示法有进制表示和科学计数

    • 科学计数法允许字母e或E的后面,跟着一个整数,表示这个数值的指数部分。
    • 进制表示有二进制、八进制、十进制、十六进制数值,前缀分别0B、0O、无前缀、0X,例如:0B10000、0O20、16、0X10为分别使用二、八、十、十六进制表示同一数值。

    ii. 普通数值的自动转换

    JavaScript 会自动将数值转为科学计数法表示。

    • 小数点后的零多于5个;
    • 小数点前的数字多于21位。

    JavaScript 内部会自动将八进制、十六进制、二进制转为十进制,数字或字母不匹配进制将会报错。

    ES5普通模式,在有前导0的数值会被视为八进制,但是如果前导0后面有数字8和9,则该数值被视为十进制。

    3.3 特殊数值

    i.正零和负零

    正零和负零都会被当作正常的0,唯一有区别的场合是当+0或-0作为分母,如1 / +0,1 / -0,0 / 0 返回的值,分别得到+Infinity,-Infinity,NaN。

    ii. NaN

    • 含义:NaN是数据类型属于Number的非数值;
    • 运算规则:NaN不等于任何值,包括它本身,NaN与任何数(包括它自己)的运算,得到的都是NaN。

    iii. Infinity

    由于数值正向溢出(overflow)、负向溢出(underflow)和被0除,JavaScript都不报错,而是返回Infinity,所以单纯的数学运算几乎没有可能抛出错误。

    Infinity + Infinity // Infinity
    Infinity * Infinity // Infinity
    Infinity - Infinity // NaN
    Infinity / Infinity // NaN
    
    0 * Infinity // NaN
    0 / Infinity // 0
    Infinity / 0 // Infinity
    
    null * Infinity // NaN
    null / Infinity // 0
    Infinity / null // Infinity
    
    undefined + Infinity // NaN
    undefined - Infinity // NaN
    undefined * Infinity // NaN
    undefined / Infinity // NaN
    Infinity / undefined // NaN
    

    Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN),Infinity与NaN比较,总是返回false。

    3.4 特殊数值判断方法

    i. isNaN()

    isNaN方法可以用来判断一个值是否为NaN,只对数值有效,如果传入其他值,会被Number函数先转成数值。

    ii. isFinite()

    除了Infinity、-Infinity、NaN和undefined这几个值会返回false,isFinite对于其他的数值都会返回true。

    4. 字符串

    4.1 概述

    字符串就是零个或多个排在一起的字符,放在单引号或双引号之中,默认只能写在一行内,ES6中可使用反引号(``)替代单双引号,让字符串写在多行。

    JavaScript 的单位字符长度固定为16位长度,只能以2个字节的UTF-16格式储存,所以处理的时候,JavaScript 返回的字符串长度可能是不正确的。

    4.2 转义

    需要用反斜杠转义的特殊字符,主要有下面这些,若前面加反斜杠没有特殊含义,反斜杠会被自动省略。

    • \0 :null(\u0000)
    • \b :后退键(\u0008)
    • \f :换页符(\u000C)
    • \n :换行符(\u000A)
    • \r :回车键(\u000D)
    • \t :制表符(\u0009)
    • \v :垂直制表符(\u000B)
    • \' :单引号(\u0027)
    • \" :双引号(\u0022)
    • \\ :反斜杠(\u005C)
    • \HHH (三个八进制数)
    • \xHH (两个十六进制数)
    • \uXXXX (四个八进制数)
    console.log('1\n2')
    // 1
    // 2
    
    '\a'
    // "a"
    
    '\172' === 'z' // true
    '\x7A' === 'z' // true
    '\u007A' === 'z' // true
    

    4.2 字符串方法

    • 使用数组的方括号运算符,用来返回某个位置的字符(位置编号从0开始)
    • length属性返回字符串的长度
    var s = 'hello';
    s[0] // "h"
    
    // 直接对字符串使用方括号运算符
    'hello'[1] // "e"
    
    s.length // 5
    

    4.3 Base64 转码

    文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号都无法打印出来,这时可以使用 Base64 编码,将它们转成可以打印的字符。另一个场景是,有时需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。

    所谓 Base64 就是一种编码方法,可以将任意值转成0~9、A~Z、a-z、+和/这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。

    i. JavaScript 原生提供两个 Base64 相关的方法。

    • btoa():ASCII码字符转为 Base64 编码;
    • atob():Base64 编码转为原来的值。

    ii. 非ASCII码字符转为Base64编码,必须中间插入一个转码环节。

    function b64Encode(str) {
      return btoa(encodeURIComponent(str));
    }
    
    function b64Decode(str) {
      return decodeURIComponent(atob(str));
    }
    
    b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
    b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
    

    5. 对象

    5.1 概述

    通常,数值、字符串、布尔值这三种类型,合称为不能再细分的原始类型,对象类型往往是由多个原始类型的值的组成,可称为合成类型。

    对象类型的组成部分的本质是无序键值对,‘键名’都是字符串,也称为属性,当为合法标识符时,则字符串引号可省略;‘键值’可以是任何数据类型,也可为函数。

    5.2 表达式还是语句

    如果没有圆括号,eval将其理解为一个代码块;加上圆括号以后,就理解成一个对象。

    eval('{foo: 123}') // 123
    eval('({foo: 123})') // {foo: 123}
    

    5.3 对象的引用

    如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。

    5.4 属性操作

    i. 读取属性

    • 点运算符和方括号运算符读取对象属性,若方括号运算符内标识符无引号,则标识符表示一变量,而非字符串;

    • 查看一个对象本身的所有属性,可以使用Object.keys方法;

    var obj = {
      key1: 1,
      key2: 2
    };
    
    Object.keys(obj);
    // ['key1', 'key2']
    
    • for...in循环用来遍历一个对象的全部属性。

    它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。

    它不仅遍历对象自身的属性,还遍历继承的属性。

    var obj = {a: 1, b: 2, c: 3};
    
    for (var i in obj) {
      console.log(obj[i]);
    }
    // 1
    // 2
    // 3
    
    • in运算符,用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true,否则返回false。

    ii. 增加属性

    允许属性的“后绑定”,使用点运算符和方括号运算符来读取“后绑定”对象属性。

    iii. 删除属性

    delete命令用于删除对象的属性,删除成功后返回true。


    三、数据转换

    1. 强制转换

    1.1 Number()、parseInt()、parseFloat()

    i. 原始类型值

    对于Number(),数值和字符串整体转换为数值,基本上只要有一个字符无法转成数值,整个字符串就会被转为NaN。布尔值true和false转换为1和0,undefined和null转换为NaN和0,

    对于parseInt(),将参数(不能识别符合科学计数法字符串)转为字符串,返回字符串有效位的整数,无有效位返回NaN。

    parseInt(字符串,进制)

    • 字符串的进制由进制参数和字符串首位决定,进制参数会被自动转为一个整数(2到36之间),进制参数是0、undefined和null,则直接忽略,返回该值对应的十进制数,字符串首位是OX,则默认进制参数为十六进制,O为首字符串参数,0将会被忽略,则默认进制参数为十进制;
    • 如果字符串包含对于指定进制无意义的字符,则从最高位开始,只返回可以转换的数值。如果最高位无法转换,则直接返回NaN;

    对于parseFloat(),将参数(能识别符合科学计数法字符串)转为字符串,返回字符串有效位的小数,无有效位返回NaN;

    parseInt,parseFloat和Number函数都会自动过滤一个字符串前导和后缀的空格。

    parseInt('\t\v\r12.34\n') // 12
    Number('\t\v\r12.34\n') // 12.34
    

    对于布尔值、null和undefined的转换值区别如下。

    数值转换 true false null undefined
    Number() 1 0 0 NaN
    parseInt() NaN NaN NaN NaN
    parseFloat() NaN NAN NaN NaN

    ii. 对象

    Number()、parseInt()、parseFloat()会将对象转换为原始数据类型,再使用Number函数将原始数据类型转为数值。

    对象转换为原始数据类型过程具体为先调用对象自身的valueOf方法,使对象能返回原始类型的值,否则改为调用对象自身的toString方法,返回原始类型的值,如果toString方法返回的还是对象,就报错。

    1.2 String()、toString()

    i. 原始类型的值

    String()函数和toString()方法功能范围:

    • 数值:转为相应的字符串,额外地,toString()方法可传入二、八、十六数值或字符串的进制参数;

    • 字符串:转换后还是原来的值;

    • 布尔值:true转为字符串"true",false转为字符串"false";

    • undefined:String()函数转为字符串"undefined",但无toString()方法;

    • null:String()函数转为字符串"null",但无toString()方法。

    ii. 对象

    String()会将对象转换为原始类型的值,和Number()相反,String()先调用toString,后调用valueOf。

    String({a: 1}) // "[object Object]"
    String([1, 2, 3]) // "1,2,3"
    

    1.3 Boolean()

    除了undefined,null,false,0,NaN,""或''(空字符串)六个值被转为false,其他都是true,包括空数组([])和空对象({})。

    2. 自动转换

    自动转换的规则是:预期是布尔值、数值、字符串的地方,会分别自动调用Boolean、Number和String函数进行转换。

    2.1 自动转换为布尔值

    i. 下列运算符会返回布尔值;

    两元逻辑运算符: && (And),|| (Or);

    前置逻辑运算符: ! (Not),!!(等价Boolean());

    相等运算符:===,!==,==,!=;

    比较运算符:>,>=,<,<=。

    ii. 程序流程的控制里,判断条件会自动会返回布尔值。

    if ([]) {
      console.log('true');
    }
    // true
    
    if ({}) {
      console.log('true');
    }
    // true
    

    2.2 自动转换为字符串

    主要发生在字符串的加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。

    2.3 自动转换为数值

    除了加法运算符(+)有可能把运算子转为字符串,其他运算符都会把两侧运算子自动转成数值。

    相关文章

      网友评论

          本文标题:JS数据类型和转换

          本文链接:https://www.haomeiwen.com/subject/asyjwftx.html