原始类型
原始类型有:数字、字符串、布尔值、null
、undefined
。
数字
- 浮点数范围:
- 最大值:正负
1.79E308
- 最小值:正负
5E-324
- 最大值:正负
- 整数范围:正负
2E53
-
0
和-0
相等,区别在于乘除法时的符号。 - 上溢出时,用
Infinity
表示。下溢出时用-Infinity
表示。 - 被
0
整除的结果是Infinity
。被-0
整除的结果是-Infinity
。 -
0
除以0
的结果是NaN
。 -
NaN
与任何值都不相等,包括自身。所以判断一个变量是否为NaN
时要用x!=x
,当表达式为true
时,x
为NaN
,或者直接使用isNaN()
函数。 - 当一个数不为
NaN
、Infinity
和-Infinity
时,isFinite()
返回true
。
字符串
- JavaScript 没有单个字符的 字符类型 。
- JavaScript 采用 UTF-16 编码的 Unicode 字符集,大多数字符用一个16位值表示,但是有些字符用两个16位值表示,称为 代理项对 。
- JavaScript 定义的字符串操作方法(包括
length()
)均作用于16位值,而非字符,不会对代理项对做特殊处理。 - 当 HTML 代码和 JavaScript 代码混杂时,最好使用
'
和"
两种引号风格,以便区分。如
- 转义字符包括:
-
\o
:NUL字符 -
\b
:退格符 -
\t
:水平制表符 -
\n
:换行符 -
\v
:垂直制表符 -
\f
:换页符 -
\r
:回车符 -
\"
:双引号 -
\'
:撇号或单引号 -
\\
:反斜线 -
\xXX
:由两个十六进制数指定的 Latin-1 字符 -
\uXXXX
:由4位十六进制数指定的 Unicode 字符
-
- 若
\
位于没有在上表中出现的字符前,则忽略\
,如\#
和#
等价。 - 相关操作方法:
var s = "string";
s.charAt(0);
s.charAt(s.length-1)
s.substring(1, 4);
s.slice(1, 4); // 同上
s.slice(-3); // 最后3个字符
s.indexOf("r"); // 字符"r"首次出现的位置
s.lastIndexOf("r"); // 字符"r"最后出现的位置
s.indexOf("r", 3); // 字符"r"在位置3之后首次出现的位置
s.split(", "); // 分割子串
s.replace("s", "S"); // 替换
s.toUpperCase();
- 字符串的操作方法不会改变字符串变量,只会返回新的字符串。
布尔值
- 布尔值只有两个直接量:
false
和true
。 - 假值:即会转化为
false
的值,其中包括undefined
、null
、0
、-0
、NaN
、""
。 - 真值:除了上面列出的值,其他所有值都会转化为
true
。 - 布尔值只有一个方法
toString()
,返回值为"true"
或"false"
。
null和undefined
-
undefined
是预定义的全局变量,而不是关键字。 - 函数没有返回值的时候,会返回
undefined
。 - 函数形参没有传入实参时,此形参的值为
undefined
。 -
null
是关键字。 -
null == undefined
返回"true"
,null === undefined
返回"false"
。 - 如果你想将它们赋值给变量或者属性,或将它们作为参数传入函数,最佳的选择是使用
null
。undefined
通常用于辨别非预期内的情况。
对象类型
- 除了原始类型以外的类型就是对象类型。
- 由属性集合组成。
- 五种特殊的对象类型:数组类型、函数类型、
Date
类型、RegExp
类型、错误类型。 - 变量都是引用,两个引用指向一个对象的时候,修改一个引用的值也会改变另一个引用。
var a = [];
var b = a;
b[0] = 1;
a[0]; // 1
a === b; // true
数组类型
- 不能直接比较,要逐个元素进行比较。
Date类型
var date1 = new Date(2017, 0, 3, 10, 11, 12); // 2017年1月3日 10时11分12秒
var date2 = new Date(2017, 0, 3, 10, 11, 13); // 2017年1月3日 10时11分13秒
var diff = date2 - date1; // 计算两个时间间隔的毫秒数
date1.getFullYear(); // 2017年
date1.getMonth(); // 0月---月份从0开始算起
date1.getDate(); // 一月的第几天
date1.getDay(); // 星期几
date1.getHours(); // 10时
date1.getMinutes(); // 11分
date1.getSeconds(); // 12秒
date1.getUTCHours(); // 使用UTC表示的小时
RegExp类型
-
RegExp
是一种特殊的 JavaScript 对象类型。 -
RegExp
直接量:在两条斜线之间的文本构成了一个RegExp
直接量,如/^HTML/
、[1-9][0-9]*
- 相关方法:
var text = "testing: 1, 2, 3";
var pattern = /\d+/g;
pattern.test(text); // true: 匹配成功
text.search(pattern); // 9
text.match(pattern); // ["1", "2", "3"]
text.replace(pattern, "#"); // testing: #, #, #
text.split(/\D+/); // ["", "1", "2", "3"]
全局对象
- 当 JavaScript 解释器启动时(或者任何 Web浏览器 加载新页面的时候),它将创建 一个 新的全局对象,这个全局对象包含:
- 全局属性:比如
undefined
、Infinity
和NaN
。 - 全局函数:比如
isNaN()
、parseInt()
和eval()
。 - 构造函数:比如
Date()
、RegExp()
、String()
、Object()
和Array()
。 - 其它全局对象:比如 Math 和 JSON 。
- 全局属性:比如
- 在 JavaScript 中可以用
this
来表示全局对象。可以在全局作用域中使用如下方法来引用全局对象:var global = this;
。 - 在客户端 JavaScript 中,在其表示的浏览器窗口中的所有 JavaScript 代码中,
Window
对象取代了this
充当了全局对象。可以在全局作用域中使用如下方法来引用全局对象:var global = Window.window;
。 -
Window
对象定义了核心的全局属性,但它也针对 Web浏览器 和客户端 JavaScript 定义了少部分其它全局属性。 - 如果代码中声明了一个全局变量,这个全局变量就是全局对象的一个属性。
包装对象
- JavaScript 中的包装对象类似 Java 中的包装器。
- JavaScript 对象时属性或已命名值的集合。通过
.
符号来引用属性值。 - 尽管数字、字符串、布尔值没有属性,但是被
.
运算符作用时,会创建对应的临时对象(Number()
、String()
、Boolean()
),此时会有属性。这个临时对象被称为包装对象。 -
null
和undefined
没有包装对象。 - 区分数字、字符串、布尔值和数字对象、字符串对象、布尔值对象:
var s = "test"; // 字符串
var n = 1; // 数字
var b = true; // 布尔值
var S = new String(s); // 字符串对象
var N = new Number(n); // 数字对象
var B = new Boolean(b); // 布尔值对象
s == S; // "true"
s === S; // "false"
n == N; // "true"
n === N; // "false"
b == B; // "true"
b === B; // "false"
- 包装对象会在作用完毕后销毁:
var s = "test";
s.len = 4;
var t = s.len; // t的值为undefined
类型转换
简介
类型转换即在 JavaScript 期望使用某种类型的时候,将其他类型转换为这种类型的过程。
值 | 字符串 | 数字 | 布尔值 | 对象 |
---|---|---|---|---|
undefined | "undefined" | NaN | false | throw TypeError |
null | "null" | 0 | false | throw TypeError |
true | "true" | 1 | new Boolean(true) | |
false | "false" | 0 | new Boolean(false) | |
"" | 0 | false | new String("") | |
"1.2" | 1.2 | true | new String("1.2") | |
"one" | NaN | true | new String("one") | |
0 | "0" | false | new Number(0) | |
-0 | "0" | false | new Number(-0) | |
NaN | "NaN" | false | new Number(NaN) | |
Infinity | "Infinity" | true | new Number(Infinity) | |
-Infinity | "-Infinity" | true | new Number(-Infinity) | |
1 | "1" | true | new Number(1) | |
{} | true | |||
[] | "" | 0 | true | |
[9] | "9" | 9 | true | |
['a'] | 使用join()方法 | NaN | true | |
function() {} | NaN | true |
转换与相等性
-
==
与===
的区别在于:==
在比较两个操作数的时候可能做了类型转换,而===
则不会做类型转换。
显式类型转换
- 当不通过
new
来调用Boolean()
、Number()
、String()
或Object()
函数时就是显式类型转换。
Number("3"); // 3
String(false); // "false"
Boolean([]); // true
Object(3); // new Number(3)
- 除了
null
或undefined
之外的任何值都具有toString()
,通常和String()
返回结果一致。
Number转换为String
var n = 123456.789;
n.toFixed(0); // "123457"
n.toFixed(2); // "123456.79"
n.toFixed(5); // "123456.78900"
n.toExponential(1); // "1.2e+5"
n.toExponential(3); // "1.235e+5"
n.toPrecision(4); // "1.235e+5"
n.toPrecision(7); // "123456.8"
n.toPrecision(10); // "123456.7890"
String转换为Number
parseInt("3 blind mice"); // 3
parseInt("-12.34"); // -12
parseInt("0xFF"); // 255
parseInt("0xff"); // 255
parseInt("0.1"); // 0
parseInt(".1"); // NaN
parseInt("11", 2); // 3
parseInt("ff", 16); // 255
parseInt("zz", 36); // 1295
parseInt("077", 8); // 63
parseInt("077", 10); // 77
parseFloat(" 3.14 meters"); // 3.14
parseFloat(".1"); // 0.1
parseFloat("$72.47"); // NaN
对象转换为原始值
- 对象转换为布尔值 的规则是:所有对象都转换为
true
,包括 包装对象new Boolean(false)
。 - 对象转换为字符串 的规则是:
- 通过
toString()
转换为字符串。 - 若没有
toString()
,则通过valueOf()
转换为数字,再转换为字符串。 - 若既没有
toString()
,也没有valueOf()
,抛出 类型错误异常 。
- 通过
- 对象转换为数字 的规则是:
- 通过
valueOf()
转换为数字。 - 若没有
valueOf()
,则通过toString()
转换为字符串,再转换为数字。 - 若既没有
toString()
,也没有valueOf()
,抛出 类型错误异常 。
- 通过
- 对象遇到
+
、==
、!=
、<
、>
、<=
、>=
时,转换规则如下:-
Date
类对象会使用toString()
转换为字符串。 - 除
Date
类以外的其他对象会使用以下规则:- 使用
valueOf()
转换为数字,然后直接使用,不会进一步转换为字符串。 - 若没有
valueOf()
,则使用toString()
转换为字符串,然后直接使用,不会进一步转换数字。
- 使用
-
- 对象遇到
-
等其他运算符,则直接使用 对象转换为数字 规则。
类型转换小技巧
x + "" // 等于String(x)
+x // 等于Number(x)
!!x // 等于Boolean(x)
变量声明
- 声明但不初始化变量时,初始值为
undefined
。 - JavaScript 没有花括号括起来的块级作用域。
- 声明提前 :局部变量声明无论在函数体内的哪里,都会被提升至函数体的开头部分,但是初始化语句不会,还是待在原来的地方。
- 多次声明同一个变量是无所谓的。
var scope = "global";
function f() {
console.log(scope); // 局部变量的scope,值为undefined,覆盖全局作用域的scope
var scope = "local"; // 虽然在这里声明,但是在整个函数作用域里是可见的。初始化语句则要运行到这一句才会真正赋值。
console.log(scope); // local
}
- 将所有函数内局部变量声明在函数体开头部分是个好习惯。
全局变量
- 当声明一个 JavaScript 全局变量时,实际上是定义了全局对象的一个属性。
- 当使用
var
声明一个变量时,创建的这个属性是不可配置的。
var a = 1; // 全局变量的声明方式一
b = 2; // 全局变量的声明方式二
this.c = 3; // 全局变量的声明方式三
delete a; // false
delete b; // true
delete c; // true