chapter 3 基本概念(3.4 数据类型)

《JavaScript高级程序设计》第三版 笔记

3.4 数据类型

ECMAScript 共有6种数据类型。

5种简单数据类型(也称基本数据类型):
Undefined、Null、Boolean、Number、String
1种复杂数据类型:
Object(object 本质上是由一组无序的名值对组成的

3.4.1 typeof 操作符

可以用来检测给定变量的数据类型。
* typeof 操作符的操作数可以是变量,也可以是数值字面量。
typeof 是一个操作符而不是函数。

对一个值使用 typeof 操作符可能返回下列某个字符串:
“undefined”–如果这个值未定义
“boolean”–如果这个值是布尔值
“string”–如果这个值是字符串
“number”–如果这个值是数值
“object”–如果这个值是对象或null(Safari 5 及之前版本、Chrome 7 及之前版本在对正则表达式调用 typeof 操作符时会返回 “function” ,而其他浏览器在这种情况下会返回 “object”
“function”–如果这个值是函数

example:

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    var one;
    var two = null;
    var three = true;
    var four = 3;
    var five = "hello world";
    var six = {name: "edward" , age: 15};
    var seven = function(){};
    console.log(typeof one);
    console.log(typeof two);
    console.log(typeof three);
    console.log(typeof four);
    console.log(typeof five);
    console.log(typeof six);
    console.log(typeof seven);
  </script>
</body>
</html>

这里写图片描述

*从技术角度来讲,函数在 ECMAScript 中是对象,而不是一种数据类型。
但是,函数确实有一些特殊属性,因此通过 typeof 操作符来区分函数和其他对象是有必要的。

3.4.2 Undefined类型

undefined 类型只有一个值,即 undefined 。
在使用 var 声明变量但未对其初始化时,这个变量的值就是 undefined 。

*比较已声明但未初始化的变量与 undefined 字面量,结果表明它们是相等的。
一般而言,不存在需要显式的把一个变量设置为 undefined 值的情况。

example:

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    var message;
    alert (message === undefined);
  </script>
</body>
</html>

这里写图片描述

关于未定义变量:
包含 undefined 值的变量与尚未声明的变量不同。(将未声明过的变量作为 alert 函数的参数会导致错误。
对于尚未声明过的变量,只能执行一项操作,即使用 typeof 检测其数据类型。
*对未声明的变量执行 typeof 操作符会返回undefined值。
对未经声明的变量调用 delete 不会导致错误,但这样做没什么实际意义,而且在严格模式下会导致错误。

为什么推荐显式的初始化变量?
如果显式的初始化变量,那么当 typeof 操作符返回 undefined 值时,我们就可以分辨出被检测变量还没有被声明,而不是尚未初始化。

3.4.3 Null类型

null 类型是第二个只有一个值的数据类型,这个特殊的值是 null 。
null 值表示一个空对象指针。

*undefined 值是派生自null值的,因此 ECMA-262 规定对它们的相对性测试要返回 true 。
(*alert(undefined === null); //false
alert(undefined == null); //true*)

只要意在保存对象的变量还没有真正保存对象,就应明确地让该变量保存 null 值。
这样做有助于进一步区分 null 和 undefined 。

example:

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    alert(undefined == null);
  </script>
</body>
</html>

这里写图片描述

3.4.4 Boolean 类型

boolean 类型只有两个字面值: true 和 false 。(这两个值是区分大小写的。

*ECMAScript 中所有类型的值都有与这两个 Boolean 值等价的值。
要将一个值转换为其对应的 boolean 值,可以调用转型函数 Boolean()

数据类型转换为 true 的值转换为 false 的值
Boolean true false
String 任何非空字符串 空字符串
Number 任何非零数字值(包括无穷大) 0 和 NaN
Object 任何对象 null
Undefined n/a (*n/a (或 N/A ),是 not applicable 的缩写,意思是“不适用”。*) false
  • 这些转换规则对理解流控制语句(如 if 语句。)自动执行相应的 Boolean 转换非常重要。

3.4.5 Number 类型

number 类型使用 IEEE754 格式来表示整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)。
* JavaScript 可以保存正零(+0)和负零(-0)。
* 正零和负零被认为相等。
为了支持各种数值类型,ECMA-262 定义了不同的数值字面量格式。

十进制整数
十进制整数是最基础的数值字面量格式。
example:
var intNum = 55; //整数

八进制整数
八进制字面量在严格模式下是无效的,会导致支持的 JavaScript 引擎抛出错误。
八进制字面值的第一位必须是 0 ,然后是八进制数字序列(0~7)。
*如果字面值中的数值超出了范围,那么前导零将被忽略,后面的数值将被当作十进制数值解析。
example:
var octalNum1 = 070; //八进制的56
var octalNum2 = 079; //无效的八进制数值 - 解析为79

十六进制整数
十六进制字面值的前两位必须是 0x,后跟任何十六进制数字 (0~9 及 A~F)。
其中,字母 A~F 可以大写,也可以小写。

example:
var hexNum1 = 0xA; //十六进制的10
var hexNum2 = 0x1f; //十六进制的31

在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值。

1. 浮点数值
浮点数值即该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。

虽然小数点前面可以没有整数,但不推荐这种写法。

example:
var floatNum1 = 0.1;
var floatNum2 = .1; //有效,但不推荐

浮点数会被转换为整数保存的情况:
由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数。
1.如果小数点后面没有跟任何数字,那么这个数值就可以作为整数值来保存。
2.如果浮点数值本身表示的就是一个整数(如1.0),那么该数值也会被转换为整数。

example:
var floatNum3 = 1. ; //解析为1
var floatNum4 = 10.0; //解析为10

对于那些极大或极小的数值,可以用e表示法(即科学计数法)。
默认情况下, ECMAScript 会将小数点后面带有6个零以上的浮点数值转换为以e表示法表示的数值(例如,0.0000003会被转换成3e-7)。

example:
var floatNum5 = 3.125e7; //即 3.125乘以10的7次方,等于31250000
var floatNum6 = 3e-10; //0.0000000003

为什么 0.1+0.2 的结果不是 0.3,而是 0.30000000000000004 ?
浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。
这个小小的舍入误差会导致无法测试特定的浮点数值。(这是使用基于 IEEE754 数值的浮点计算的通病。

example:
if (a + b == 0.3){ //不要做这样的测试!
alert(“you got 0.3”);
}

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    alert(0.1 + 0.2);
  </script>
</body>
</html>

这里写图片描述

2. 数值范围
由于内存的限制, ECMAScript 并不能保存世界上所有的数值。
ECMAScript 能够表示的最小数值保存在 Number.MIN_VALUE 中,在大多数浏览器中,这个值是 5e-324
最大数值保存在 Number.MAX_VALUE 中,在大多数浏览器中,这个值是 1.7976931348623157e+308

如果某次计算结果得到了一个超出范围的值,那么这个数值将被自动转换成特殊的 Infinity 值。
如果这个数值是负数,则会被转换成 -Infinity (负无穷)。
如果这个数值是正数,则会被转换成 Infinity (正无穷)。

isFinite() 函数
Infinity 是无法参与计算的数值。
isFinite() 函数在参数位于最小与最大数值之间时会返回 true ,反之则返回false。

3. NaN
NaN ,即非数值 (Not a Number)是一个特殊的数值,这个数值用于表示 一个本来要返回数值的操作数未返回数值 的情况(这样就不会抛出错误了)。
在 ECMAScript 中,任何数值除以0会返回 NaN ,因此不会影响其他代码的执行。
+经测试,在Firefox和chrome中,alert(1/0),返回 infinity 。

NaN 的特点
1.任何涉及 NaN 的操作(例如 NaN/10)都会返回 NaN ,这个特点在多步计算中有可能导致问题。
2. NaN 与任何值都不相等,包括 NaN 本身。

example:
alert(NaN == NaN); //false

isNaN()函数
isNaN() 接受一个可以是任何类型的参数。
接受参数后它会尝试将这个值转换为数值,任何不能被转换为数值的值都会导致这个函数返回 true 。

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

example:
alert(isNaN(NaN)); //true
alert(isNaN(10)); //false(10是一个数值)
alert(isNaN(“10”)); //false(可以被转换成数值10)
alert(isNaN(“blue”)); //true(不能转换成数值)
alert(isNaN(true)); //false(可以被转换成数值1)

4. 数值转换
有三个函数可以把非数值转换为数值:
Number()、parseInt()、parseFloat()

三个函数的区别:
转型函数 Number() 可以用于任何数据类型。
parseInt()、 parseFloat() 则专门用于把字符串转换成数值
这3个函数对于同样的输入会返回不同的结果。

Number() 函数的转换规则:

Boolean 值:
true 和 false 将分别被转换为 1 和 0 。

数字值:
只是简单的传入和返回。

null 值:
返回 0 。

undefined :
返回 NaN 。

字符串:
1.只包含数字的字符串(包括前面带正号或负号的情况),则将其转换为十进制数值;
若首位是 0 ,则前导的 0 会被忽略。
2.包含有效的浮点格式的字符串,如 “1.1” ,则将其转换为对应的浮点数值;
同样会忽略前导 0 。
3.包含有效的十六进制格式,例如 “0xf” ,则将其转换为相同大小的十进制整数。
+包含有效的八进制格式,则将其转换为相同大小的十进制整数。
4.字符串为空,则将其转换为 0 。
5.包含除上述格式之外的字符的字符串,则将其转换为 NaN 。

对象:
调用对象的 valueOf() 方法,然后依照前面的规则转换返回的值;
如果转换的结果是 NaN ,则调用对象的 toString() 方法,然后再依照前面的规则转换返回的字符串值。

example:

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    window.onload = function(){
      document.write("true :" + Number(true) + "<br>");
      document.write("123 :" + Number(123) + "<br>");
      document.write("0123 :" + Number(0123) + "<br>");
      document.write("0888 :" + Number(0888) + "<br>");
      document.write("-123 :" + Number(-123) + "<br>");
      document.write("1.1 :" + Number(1.1) + "<br>");
      document.write("0.1 :" + Number(0.1) + "<br>");
      document.write("0.10 :" + Number(0.10) + "<br>");
      document.write("null :" + Number(null) + "<br>");
      document.write("undefined :" + Number(undefined) + "<br>");
      document.write("\"123\" :" + Number("123") + "<br>");
      document.write("\" 123\" :" + Number(" 123") + "<br>");
      document.write("\" 1 2 3\" :" + Number(" 1 2 3") + "<br>");
      document.write("\"1 23\" :" + Number("1 23") + "<br>");
      document.write("\"0123\" :" + Number("0123") + "<br>");
      document.write("\"-123\" :" + Number("-123") + "<br>");
      document.write("\"1.1\" :" + Number("1.1") + "<br>");
      document.write("\"0.1\" :" + Number("0.1") + "<br>");
      document.write("\"0.10\" :" + Number("0.10") + "<br>");
      document.write("\"1.2.3\" :" + Number("1.2.3") + "<br>");
      document.write("\"0xf\" :" + Number("0xf") + "<br>");
      document.write("\"\" :" + Number("") + "<br>");
      document.write("\"hello world\" :" + Number("hello world") + "<br>");
      document.write("\"hello 123\" :" + Number("hello 123") + "<br>");
      document.write("\"123 world\" :" + Number("123 world") + "<br>");
      document.write("{name:\"jame\",age:12} :" + Number({name:"jame",age:12}) + "<br>")
      document.write("[1,2,3] :" + Number([1,2,3]) + "<br>");
    }
  </script>
</body>
</html>

这里写图片描述

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

parseInt() 函数的转换规则:

字符串:
1.它会忽略字符串前面的空格,直至找到第一个非空格字符。
2.如果第一个字符不是数字字符或负号, parseInt() 会返回 NaN
空字符串返回 NaN
3.如果第一个字符是数字字符,则会继续解析,直到解析完所有后续字符或者遇到了一个非数字字符(例如 “1234blue” 会被转换为 1234 。);
“22.5” 会被转换为 22 ,因为小数点并不是有效的数字字符。

4.在使用 parseInt() 解析像八进制字面量的字符串时, ECMAScript 3 会将其转换为对应的十进制数值;而 ECMAScript 5 会将其转换为 0 (前导的 0 会被认为无效,从而将这个值当成 “0”,在严格模式下也会如此)。
+经测试(Firefox 57.0.4)第4条已不符合,八进制会忽略前面的 0 ,当做十进制数值解析。十六进制即使不指定基数,也会按照十六进制解析。

5.为了正确解析其他进制字面量字符串, parseInt() 可以传入第二个参数–转换时使用的基数(即多少进制);
如果指定了 16 作为第二个参数,字符串可以不带前面的 “0x” 也能正确转换为十六进制数值。
6.明确指定基数,可以避免错误,建议无论什么情况下都明确指定基数,十进制数也是如此。
+将 infinity作为参数会导致错误,阻塞后面的脚本。

example:

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    window.onload = function () {
      document.write("\" 123\" : " + parseInt(" 123") + "<br>");
      document.write("\" -123\" : " + parseInt(" -123") + "<br>");
      document.write("\" 0123\" : " + parseInt(" 0123") + "<br>");
      document.write("\" a123\" : " + parseInt(" a123") + "<br>");
      document.write("\" -123\" : " + parseInt(" -123") + "<br>");
      document.write("\"123blue\" : " + parseInt("123blue") + "<br>");
      document.write("\"22.5\" : " + parseInt("22.5") + "<br>");
      document.write("\"1.0\" : " + parseInt("1.0") + "<br>");
      document.write("\"010\" : " + parseInt("010") + "<br>");
      document.write("\"010\",8 : " + parseInt("010",8) + "<br>");
      document.write("\"0xf\" : " + parseInt("0xf") + "<br>");
      document.write("\"0xf\",16 : " + parseInt("0xf",16) + "<br>");
      document.write("\"f\" : " + parseInt("f") + "<br>");
      document.write("\"f\",16 : " + parseInt("f",16) + "<br>");
      document.write("\"hello world\" : " + parseInt("hello world") + "<br>");
      document.write("null : " + parseInt(null) + "<br>");
      document.write("undefined : " + parseInt(undefined) + "<br>");
      document.write("{name:\"jame\",age:12} :" + parseInt({name:"jame",age:12}) + "<br>");
      document.write("[1,2,3] :" + parseInt([1,2,3]) + "<br>");
    }
  </script>
</body>
</html>

这里写图片描述

parseFloat() 函数的转换规则:
1.从第一个字符开始解析,一直到字符串末尾或者遇到一个无效的浮点数字字符为止;
即字符串中的第一个小数点是有效的,而第二个小数点无效,它后面的字符串将被忽略。
2.始终忽略前导零。
3.只解析十进制值;
没有用第二个参数指定基数的用法;
十六进制格式的字符串会被转换成 0 。
4.可解析为整数的数(没有小数点或小数点后都是 0) ,则会返回整数。

example:

<!DOCTYPE html>
<html lang="zh-cmn-hans">
<head>
  <meta charset="utf-8">
  <title>Title</title>
</head>
<body>

  <script>
    window.onload = function () {
      document.write("\"1.2.3\" : " + parseFloat("1.2.3") + "<br>");
      document.write("\" 1.2.3\" : " + parseFloat(" 1.2.3") + "<br>");
      document.write("\"-1.2.3\" : " + parseFloat("-1.2.3") + "<br>");
      document.write("\"01.2.3\" : " + parseFloat("01.2.3") + "<br>");
      document.write("\"1.20\" : " + parseFloat("1.20") + "<br>");
      document.write("\"5.0\" : " + parseFloat("5.0") + "<br>");
      document.write("\"5\" : " + parseFloat("5") + "<br>");
      document.write("\"1.2hello\" : " + parseFloat("1.2hello") + "<br>");
      document.write("\"hello1.2\" : " + parseFloat("hello1.2") + "<br>");
      document.write("\"null\" : " + parseFloat(null) + "<br>");
      document.write("\"undefined\" : " + parseFloat(undefined) + "<br>");
      document.write("\"{age:1.2}\" : " + parseFloat({age:1.2}) + "<br>");
      document.write("\"[1.2,1.3]\" : " + parseFloat([1.2,1.3]) + "<br>");
      document.write("\"\" : " + parseFloat("") + "<br>");
      document.write("1.2 : " + parseFloat(1.2) + "<br>");
    }
  </script>
</body>
</html>

这里写图片描述

3.4.6 String 类型

即字符串,用于表示由零或多个16位 Unicode 字符组成的字符序列。
字符串可以由双引号或单引号表示。
任何字符串的长度都可以通过访问其 length 属性获取。
如果字符串中包含双字节字符,那么 length 属性可能不会精确地返回字符串中的字符数目。

1. 字符字面量
转义序列,用于表示非打印字符,或者具有其他用途。
这些字符字面量可以出现在字符串中的任何位置,将被作为一个字符来解析。

字面量含义
\n换行
\t制表
\b空格
\r回车
\f进纸
\\斜杠
\’单引号( ’ ),在用单引号表示的字符串中使用。
\”双引号( ” ),在用双引号表示的字符串中使用。
\xnn以十六进制代码nn表示的一个字符(其中 n 为 0~F)。例如,\x41 表示 “A”
\unnnn以十六进制代码 nnnn 表示的一个 Unicode 字符(其中 n 为 0~F)。例如, \u03a3 表示希腊字符 Σ

2. 字符串的特点

3. 转换为字符串
要把一个值转换为字符串有两种方式。

toString() 方法
数值、布尔值、对象和字符串值都有 toString() 方法。
null 和 undefined 值没有这个方法。

在调用数值的 toString() 方法时,可以传递一个参数-输出数值的基数。
toString() 默认以十进制格式返回数值的字符串表示。
通过传递参数, toString() 方法可以输出二进制、八进制、十六进制,乃至其它任意有效进制格式表示的字符串值。

String() 函数
在不确定要转换的值是不是 null 和 undefined 的情况下,可以使用 String()

String() 函数能够将任何类型的值转换为字符串。

String() 函数转换规则:
1.如果值有 toString() 方法,则调用该方法。
2.如果值是 null ,则返回 “null” 。
3.如果值是 undefined ,则返回 “undefined” 。

example:
String(undefined); //结果为“undefined”

*要把某个值转换为字符串,可以使用加号操作符把它与一个字符串加在一起。

3.4.7 Object 类型

ECMAScript中的对象其实就是一组数据和功能的集合。
创建 Object 类型的实例并为其添加属性和方法,就可以创建自定义对象。
*在 ECMAScript 中, Object 类型是所有它的实例的基础。
Object 类型所具有的任何属性和方法,也同样存在于更具体的对象中。
Object 的每个实例都具有下列属性和方法:
Constructor
保存着用于创建当前对象的函数;
对于 var obj = new Object(); 来说,构造函数就是 Object() 。

hasOwnProperty(propertyName)
检查给定的属性在当前实例中(而不是在实例的原型中)是否存在。
作为参数的属性名必须以字符串形式指定。
(例如:obj.hasOwnProperty(“name”))

isPrototypeOf(object)
用于检查传入的对象是否是另一个对象的原型。

propertyIsEnumerable(propertyName)
检查给定的属性是否能够使用for-in语句来枚举。
作为参数的属性名必须以字符串形式指定。

toLocaleString()
返回对象的字符串表示。
该字符串与执行环境的地区对应。

toString()
返回对象的字符串表示。

valueOf()
返回对象的字符串、数值或布尔值表示。
通常与 toString() 方法的返回值相同。

*Object 是所有对象的基础,因此所有对象都具有这些基本的属性和方法。
浏览器环境中的对象,比如 BOM 和 DOM ,都属于宿主对象,它们是由宿主实现提供和定义的,因此宿主对象可能会也可能不会继承 Object 。

对象可以通过执行 new 操作符 + 要创建的对象类型的名称 来创建。

example:
var obj = new Object();
var obj = new Object; //如果不给构造函数传参,则可以省略括号。这种写法有效,但不推荐。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值