原始类型
原始类型有:数字、字符串、布尔值、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 代码混杂时,最好使用
'和"两种引号风格,以便区分。如
<button onclick="alert('Thank you')">Click Me</button>
- 转义字符包括:
-
\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