JavaScript—数据类型

JavaScript 数据类型

数据类型

ECMAScript 中有5中基本数据类型(Defined, Null, Boolean, Number, String), 和一种复杂数据类型(Object)

Undefined

  • Undefined类型只有一个值,即undefined;

  • 在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined;

    1
    var test;        // undefined
  • 对未初始化的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined值;

    1
    2
    3
    var var1;
    typeof var0; // undefined
    typeof var1; // undefined
  • 无论在什么情况下都没有必要把一个变量的值显式地设置为undefined;

Null

  • Null类型只有一个值,即null;

  • null值表示一个空对象指针,而这也正是使用typeof操作符检测null值时会返回”object”的原因;

    1
    2
    var var0=null;
    typeof var0; // Object
  • undefined值是派生自null值的,null和undefined之间的相等操作符(==)总是返回true;

    1
    later(null == undefined);   // true
  • 只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null值。这样做不仅可以体现null作为空对象指针的惯例,而且也有助于进一步区分null和undefined;

Boolean

  • Boolean类型只有两个字面值:true和false;

  • ECMAScript类型的值都有与这两个Boolean值等价的值。

数据类型 转换为true值 转换为false值
Boolean true false
String 任何非空字符串 “‘(空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined 不适用 undefined
  • 要将一个值转换为其对应的Boolean值,可以调用转型函数Boolean();
    1
    2
    var var0=null;
    Boolean(var0); // false

Number

  • Number类型代表整数和浮点数值;

  • 除了以十进制表示外,整数还可以通过八进制(以0开头)或十六进制(以0x开头)的字面值来表示;

    1
    2
    var octal = 023;    // 十进制19
    var hex=0xff; // 十进制255

浮点数

  • 由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数值;

    1
    2
    var floatNum1 = 1.;     // 1
    var floatNum2 = 10.00; // 10
  • 浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数;

    1
    var calc = 0.1 + 0.2;   // 0.30000000000000004

数值范围

  • ECMAScript能够表示的最小数值保存在Number.MIN_VALUE中,最大数值保存在Number.MAX_VALUE中;

  • 如果某次计算的结果得到了一个超出JavaScript数值范围的值,那么这个数值将被自动转换成特殊的Infinity值;

  • Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY也可以得到负和正Infinity的值;

  • Infinity不是能够参与计算的数值;

  • 要想确定一个数值是不是有穷的可以使用isFinite()函数;

    1
    2
    isFinite(1234);     // true
    isFinite(Number.MAX_VALUE + Number.MAX_VALUE); // false

NaN

  • NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数却未返回数值的情况;

  • 在ECMAScript中,任何非数值除以0会返回NaN, 数值除以0返回Infinity;

    1
    2
    console.log("hello world"/0);   // NaN
    console.log(10/0); // Infinity
  • 任何涉及NaN的算术操作(例如NaN/10)都会返回NaN;

    1
    console.log(10 + NaN)   // NaN
  • NaN与任何值都不相等,包括NaN本身;

    1
    console.log(NaN == NaN);    // false
  • isNaN()函数用于参数是否“不是数值”,isNaN()在接收到一个值之后,会尝试将这个值转换为数值。而任何不能被转换为数值的值都会导致这个函数返回true;

    isNaN()确实也适用于对象。在基于对象调用isNaN()函数时,会首先调用对象的valueOf()方法,然后确定该方法返回的值是否可以转换为数值。如果不能,则基于这个返回值再调用toString()方法,再测试返回值。而这个过程也是ECMAScript中内置函数和操作符的一般执行流程

数值转换

  • Number()函数
    • 如果是Boolean值,true和false将分别被转换为1和0
    • 如果是数字值,只是简单的传入和返回
    • 如果是null值,返回0
    • 如果是undefined,返回NaN
    • 如果是字符串,遵循下列规则
      • 如果字符串中只包含数字(包括前面带加号或头号的情况),则将其转换为十进制数值,即”1”会变成1,”123”会变成123,而”011”会变成11(注意:前导的零被忽略了);
      • 如果字符串中包含有效的浮点格式,如”1.1”,则将其转换为对应的浮点数值(同样,也会忽略前导零);
      • 如果字符串中包含有效的十六进制格式,例如”Oxf”,则将其转换为相同大小的十进制整数值;
      • 如果字符串是空的(不包含任何字符),则将其转换为0;
      • 如果字符串中包含除上述格式之外的字符,则将其转换为NaN。
    • 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      Number(true);       // 1
      Number(00011); // 9, 8进制转为10进制
      Number(0xff); // 255, 16进制转10进制
      Number(null); // 0
      Number(undefined); // NaN
      Number("0001.01"); // 1.01, 忽略前导0
      Number("0xff"); // 255
      Number(" "); // 0
      Number("1 1"); // NaN

由于Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是parseInt()函数

  • parseInt()函数

    • parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。它会忽略字符串前面的空格,直至找到第一个非空格字符;
    • 如果第一个字符不是数字字符或者正、负号,parseInt()就会返回NaN;
    • 如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符;
    • parseInt()能够识别出整数格式(八进制和十六进制)。ECMAScript 3和5存在分歧,ECMAScript3中,前导”0”被当成八进制字面量,而在ECMAScript5中前导的零会被认为无效;
    • 为了消除在使用parseInt()函数时可能导致的上述困惑,可以为这个函数提供第二个参数:转换时使用的基数;
      1
      2
      3
      4
      5
      6
      parseInt("   1234");    // 1234
      parseInt("1234asdf"); // 1234
      parseInt("+1234asdf"); // 1234
      parseInt("+123.4"); // 123
      parseInt("01234"); // 1234, ECMAScript5中前导0无效
      parseInt(01234, 8); // 54, 第二个参数指定基数
  • parseFloat()函数

    • 与parseInt()函数类似,但是不能能够识别出整数格式(八进制和十六进制),只解析十进制值。因此它没有用第二个参数指定基数的用法;
    • 如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是零),parseFloat()会返回整数;
      1
      2
      3
      parseFloat("1234abc");  // 1234
      parseFloat("1234.00"); // 1234
      parseFloat("0x1234"); // 0

String

  • String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串;

  • 如果字符串中包含双字节字符,那么length属性可能不会精确地返回字符串中的字符数目;

  • ECMAScript中的字符串是不可变的;

其它类型转换为String

  • toString()
    • 数值、布尔值、对象和字符串值(没错,每个字符串也都有一个toString()方法,该方法返回字符串的一个副本)都有toString()方法。但null和undefined值没有这个方法;
    • 在调用数值的toString()方法时,可以传递一个参数:输出数值的基数;
1
2
3
var num = 10;
num.toString(); // "10"
num.toString(2); // "1010"
  • String()
    • 在不知道要转换的值是不是null或undefined的情况下,还可以使用转型函数String();
    • String()函数遵循下列转换规则:
      • 如果值有toString()方法,则调用该方法(没有参数)并返回相应的结果;
      • 如果值是null,则返回”null”;
      • 如果值是undefined,则返回”undefined”
        1
        2
        3
        4
        5
        6
        var num = 10;
        var obj = null;
        var var0;
        String(num); // "10"
        String(obj); // "null"
        String(var0); // "undefined"

Object

  • ECMAScript中的对象其实就是一组数据和功能的集合;

  • 可以通过执行new操作符后跟要创建的对象类型的名称来创建;

    1
    2
    var obj = new Object();
    var obj1 = new Object; //有效,但不推荐省略圆括号
  • Object类型是所有它的实例的基础,就像Java中的java.lang.Object对象一样;

  • Object的每个实例都具有下列属性和方法:

    • Constructor : 保存着用于创建当前对象的函数
    • hasOwnProperty(propertyName) : 用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在
    • isPrototypeOf(object) : 用于检查传入的对象是否是另一个对象的原型
    • propertyIsEnumerable(propertyName) : 用于检查给定的属性是否能够使用for-in语句
    • toLocaleString() : 返回对象的字符串表示,该字符串与执行环境的地区对应
    • toString() : 返回对象的字符串表示
    • valueOf() : 返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同
1
2
3
4
5
6
7
8
var obj = new Object();
obj.field = "Field"

obj.constructor; // ƒ Object() { [native code] }
obj.hasOwnProperty("field"); // true
obj.propertyIsEnumerable("field"); // true
obj.toLocaleString(); // "[object Object]"
obj.toString(); // "[object Object]"

typeof 检测数据类型

对一个值使用typeof操作符可能返回下列某个字符串:

返回字符串 含义
undefined 值未定义
boolean 值是布尔值
string 值是字符串
number 值是数值
object 值是对象或null
function 值是函数

注意,typeof是一个操作符而不是函数,因此例子中的圆括号尽管可以使用,但不是必需的;

1
2
3
typeof 100;     // "number"
typeof "10"; // "String"
typeof null; // "object"