JavaScript基本概念——数据类型

What doesn't kill you makes you stronger.

ECMAScript中有5种简单(基本)数据类型:Undefined、Null、Boolean、Number和String。
ECMAScript有一种复杂数据类型:Object,其本质是由一组无序的键值对组成的。

typeof操作符

用于检测给定变量或字面量的数据类型。可能返回下列某个字符串:

  • "undefined"
  • "boolean"
  • "string"
  • "number"
  • "object"
  • "function"

注意typeof是操作符,不是函数,因此其后的括号是可以省略的。
函数在ECMAScript中是对象,但是函数又有一些特殊属性,因此区分函数与其他对象是有必要的。
特别的,当typeof返回"object",不代表这个值是一定是对象,它也有可能是null,因为null被认为是一个空的对象引用。

1.Undefined类型

此类型只有一个值:undefined。这个值在ECMA-262第3版被引入,用以区分空对象指针与未初始化的变量。
var message ;
相当于
var message = undefined;
对一个未声明的变量和一个声明但未赋值的变量,执行typeof操作符都返回"undefined"值。
未声明变量唯一能执行的操作是typeof 。

2.Null类型

此类型只有一个值:null。null表示一个空对象指针,因此对null执行typeof操作符返回"object"。
如果你定义了一个变量准备用来保存对象,并且想知道该变量是否保存了对象,那你应该将该变量初始化为null,而后你只要检查null值即可。
因为undefined是派生自null,因此ECMA-262规定null==undefined总是返回true。尽管它们相等,但它们的用途完全不同,我们在任何时候都没有必要的将一个变量的值显式设置为undefined,但是某些情况下显式设置为null是有必要的。

3.Boolean类型

此类型只有两个值:true和false。因为ECMAScript中的一切都区分大小写,所以True和False都不是Boolean值,只是普通的标识符(关键字、保留字、true、false、null不能用作标识符)。
虽然Boolean类型的字面量只有两个,但是ECMAScript中所有类型的值都有与之等价的值,可以调用转型函数Boolean()将一个任意类型的值转换为对应的Boolean值。
数据类型|转换为true|转换为false
-|---|---
Boolean|true|false
String|任何非空字符串|""空字符串
Number|任何非零数字值(含无穷大)|0和NaN
Object|任何对象|null
Undefined|n/a(不适用,因为Undefined只有一个值)|undefined
Null|n/a(不适用,因为Null只有一个值)|null

4.Number类型

此类型使用IEEE 754格式来表示整数和浮点数值。

JavaScript 中的所有数字都存储为 64 位(8字节)浮点数。
JavaScript 不是类型语言。与许多其他编程语言不同,JavaScript 不定义不同类型的数字,比如整数、短整数、长整数、浮点数等等。

整数可以通过十进制,八进制和十六进制表示。其中八进制字面量的第一位必须是零,然后是八进制的数字序列(0-7),如果序列出现8或9,则无视前导零当作十进制解析。八进制在严格模式下无效。
十六进制字面值的前两位必须是0X,然后是任何十六进制数(字母A-F不限大小写)。
在进行算术运算时,所有整数都会被转换成十进制数值。

浮点数值

所谓浮点数值,就是该数值中必须包含一个小数点,且小数点后至少有一位数字,小数点前面可以没有整数但不推荐这样写。
保存浮点数值所需内存空间是整数值的两倍,因此如果小数点后面没有有效数字,那么这个浮点数会被保存为整数。
极大或极小值用科学记数法表示(e不限大小写),如3.125e7。默认情况下,ECMAScript会将小数点后带6个零以上的浮点数转为以科学记数法表示的数值。浮点数值最高精度是17位小数,但计算精确度远远不如整数,所以永远不要测试某个特定的浮点数值(这是使用基于IEEE 754数值的浮点计算的语言的通病)。

数值范围

由于内存限制,ECMAScript并不能保存所有数值,它能表示的最大数值保存在Number.MAX_VALUE中(通常是1.7976931348623157e+308),最小数值保存在Number.MIN_VALUE中(通常是5e-324)。如果计算得到了超出数值范围的值,这个值将被自动转换成特殊的Infinity值(即负无穷-Infinity和正无穷Infinity)。Infinity值无法继续参与计算。可以使用isFinite()函数确定数值是否有穷。

NaN

NaN(Not a Number)是一个特殊的数值,用于表示一个本来要返回数值的操作数未返回数值的情况(从而避免抛出异常)。例如,ECMAScript中数值除以非数值会返回NaN,而其他语言则会因异常而停止代码运行。
NaN有两个特点,第一是任何涉及NaN的操作都会返回NaN,第二是NaN不等于任何值(包括NaN本身)。
依据这两个特点,ECMAScript定义了isNaN()函数,用于确定传入参数是否不是数值(函数会尝试转换参数为数值,转换失败则返回true)(当传入一个对象时,函数会先调用对象的valueOf()方法,若返回值不能转换为数值,则基于此返回值再调用toString()方法)。

数值转换

有三个函数将非数值转换为数值:Number()、parseInt()、parseFloat(),第一个可以用于任何数据类型,第二第三则专门把字符串转换为数值。

  1. 对于Number()函数,遵循以下规则:
  • 如果是Boolean值,true转为1,false转为0
  • 如果是数字值,不变
  • 如果是null值,返回0
  • 如果是undefined,返回NaN
  • 如果是字符串,则遵循以下规则:
    • 如果字符串中只包含数字(包括带正负号的情况),则将其转为十进制数字(忽略前导零)
    • 如果字符串中只包含浮点数(包括带正负号的情况),则将其转为对应数字(忽略前导零)
    • 如果字符串中只包含十六进制数,则将其转为对应十进制数字(忽略前导零)
    • 如果字符串为空,则转为0
    • 如果字符串中包含除以上格式之外的字符,则转为NaN
  • 如果是对象,则调用该对象的valueOf()方法,然后依据上面规则转换返回值,如果结果为NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串
  1. 对于parseInt()函数,它在转换字符串的时候,更多的是看其是否符合数值模式。它会忽略字符串前面的空格。如果第一个非空格字符不是正负号或者数字,它会返回NaN(这意味着它对空字符串也会返回NaN,而Number()会返回0)。parseInt()会从第一个非空格字符开始解析,直到它遇到了一个非数字字符(包括小数点)或者全部解析完成。
    如果字符串以0或者0x开头且后跟数字,parseInt()也能正确识别为对应进制数值。

    "-0xf"使用Number()得到的结果是NaN,而使用parseInt()得到的结果是-15,可见Number()函数不够合理,因此处理整数的时候更常用的是parseInt()函数。

    在ECMAScript 3 JavaScript引擎中,"077"被认为是八进制字面量,而在ECMASript 5 JavaScript引擎中,parseInt()不再具备解析八进制的能力,因此前导的零会被忽略,即使在非严格模式依然如此。parseInt()允许提供第二个参数以指定进制,为了避免解析出错,无论什么情况下都应该明确指定进制数。
  2. parseFloat()也是从第一个字符开始解析字符,直到字符串末尾或者遇见无效的浮点数字字符(第一个小数点是有效字符)。parseFloat()始终会忽略前导零。parseFloat()只解析十进制值,因此解析十六进制数的结果始终是0,同样的它也没有第二个参数用于指定进制。特别的,如果字符串包含的是一个可解析为整数的数,parseFloat()会返回整数。

5.String类型

String类型用于表示字符串(零个或多个16位Unicode字符组成的字符序列)。字符串可以由单引号或双引号表示(PHP中单双引号的解释方式不同,但ECMAScript相同)。

  1. 字符字面量
    String类型包含一些特殊的字面量,也叫转义字符:
字面量 含义
\n 换行
\t 制表(tab)
\b 退格(退格\b无法输出到屏幕上,只有输出到打印机上或者输出至文件才会起作用)
\r 回车(同上)
\f 换页
\\ 斜杠
\' 单引号
\" 双引号
\xnn 以十六进制码nn表示的一个ASCII字符(n为0~F),如"\x41",对应ASCII的第65个字母"A"
\unnnn 以十六进制码nnnn表示的一个Unicode字符(n为0~F),如"\u4e2d",对应Unicode的字符"中"

任何字符串的长度都可以通过访问其length属性获得,字符串包含多字节字符时,length属性可能不会精确的返回字符串中的字符数(不同的编码里面汉字长度不同,GBK编码一个汉字占两个字节,UTF-8编码通常汉字占三个字节,扩展B区以后的汉字占四个字节)。

  1. 字符串的特点
    ECMAScript中字符串是不可变的(Java也如此),一旦创建,它的值就不能改变。
    例如,要实现字符串拼接操作,先要创建一个长度合适的新字符串,创建待拼接的字符串,然后往新字符串中填充原来的和待拼接的字符串,最后销毁原来的字符串和待拼接的字符串。这些都是后台完成的,所以在一些旧版本浏览器(如1.0之前的FireFox,IE 6等)中,拼接字符串的速度很慢。

  2. 转换为字符串
    有三种转换任意值为字符串的方法:
  • 第一种是调用其toString()方法(null和undefined没有这个方法),如果该值为数值,那么这个方法可以传入一个参数以作为输出数值的进制数;
  • 第二种方法是调用转型函数String(),这个函数能处理转换值为null或者undefined的情况(返回其字面量),但不能传入参数;
  • 第三种方法是使用加号操作符,将该值与一个空字符串相加。

6.Object类型

ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符+创建的对象类型名来创建。例如:
var obj = new Object();
在ECMAScript中,如果不给构造函数传参数,则可以省略圆括号(不建议这样做)。

在ECMAScript中,Object类型是其所有实例的基础(就像在Java中java.lang.Object是所有对象的基础一样)。每个Object的实例都具有下列属性和方法:

  • constructor:保存用于创建当前对象的函数(构造函数),例如Object()
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在(注意是实例而非原型),参数必须是字符串,例如obj.hasOwnproperty("name")
  • isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型
  • propertyIsEnumerable(propertyName):用于检查给定的属性是否能枚举(使用for-in语句),参数必须是字符串
  • toLocaleString():以当地的语言返回对象的字符串表示
  • toString():返回对象的字符串表示
  • valueOf():返回对象最合适的原始值(字符串、数值或布尔值)表示

toString()和valueOf()一般都由JavaScript隐式调用,在数值运算中优先调用valueOf(),在字符串运算中优先调用toString()。在出现"+"操作符的情况下JavaScript默认两边的值是Number,所以会优先调用valueOf()。

ECMA-262中的对象的行为不一定适用于JavaScript(ECMAScript只是JavaScript的核心)中的其他对象。例如,浏览器环境中的BOM和DOM对象(都是由宿主定义和实现的宿主对象),就不完全适用ECMA-262中的对象的行为。这是因为ECMA-262不负责定义宿主对象,所以宿主对象不一定会继承Object对象。

猜你喜欢

转载自www.cnblogs.com/zhangjun2013551829/p/9449721.html