数据类型
Number类型
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity
十六进制用 0x 前缀和 0-9,a-f 表示,例如:0xff00,0xa5b4c3d2,等等
字符串
字符串是以单引号 ’ 或双引号 " 括起来的任意文本
如果字符串内部既包含’ 又包含 " 怎么办?可以用转义字符 \ 来标识,比如:
'I\'m \"OK\"!';
表示的字符串内容是:I’m “OK”!
比如 \n 表示换行,\t 表示制表符,字符 \ 本身也要转义,所以 \\ 表示的字符就是 \。
\x##形式的十六进制表示,例如:
'\x41'; // 完全等同于 'A'
还可以用 \u####表示一个 Unicode 字符:
'\u4e2d\u6587'; // 完全等同于 '中文'
模板字符串
要把多个字符串连接起来,可以用 + 号连接:
var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!';
alert(message);
ES6 新增了一种模板字符串,表示方法和上面的多行字符串一样,但是它会自动替换字符串中的变量:
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
alert(message);
运行结果:你好,小明,你今年20岁了!
操作字符串
字符串常见的操作如下:
var s = 'Hello, world!';
s.length; // 13
要获取字符串某个指定位置的字符,使用类似 Array 的下标操作,索引号从 0 开始:
var s = 'Hello, world!';
s[0]; // 'H'
s[6]; // ' '
s[7]; // 'w'
s[12]; // '!'
s[13]; // undefined 超出范围的索引不会报错,但一律返回undefined
toUpperCase
toUpperCase() 把一个字符串全部变为大写:
var s = 'Hello';
s.toUpperCase(); // 返回'HELLO'
toLowerCase
toLowerCase() 把一个字符串全部变为小写:
indexOf
indexOf() 会搜索指定字符串出现的位置:
var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 没有找到指定的子串,返回-1
substring
substring() 返回指定索引区间的子串:
var s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'
数组
JavaScript 的 Array 可以包含任意数据类型,并通过索引来访问每个元素。
请注意,直接给 Array 的 length 赋一个新的值会导致 Array 大小的变化:
var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]
请注意,如果通过索引赋值时,索引超过了范围,同样会引起 Array 大小的变化
indexOf() Array 可以通过 indexOf() 来搜索一个指定的元素的位置。
slice
slice() 就是对应 String 的 substring() 版本,它截取 Array 的部分元素,然后返回一个新的 Array:
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
push 和 pop
push() 向 Array 的末尾添加若干元素,pop() 则把 Array 的最后一个元素删除掉
unshift 和 shift
如果要往 Array 的头部添加若干元素,使用 unshift() 方法,shift() 方法则把 Array 的第一个元素删掉
sort() 可以对当前 Array 进行排序,它会直接修改当前 Array 的元素位置,直接调用时,按照默认顺序排序
reverse() 把整个 Array 的元素给掉个个,也就是反转
splice
splice() 方法是修改 Array 的 “万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
concat
concat() 方法把当前的 Array 和另一个 Array 连接起来,并返回一个新的 Array:
var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
added; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']
join
join() 方法是一个非常实用的方法,它把当前 Array 的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
对象
JavaScript 的对象是一组由键 - 值组成的无序集合,例如:
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
JavaScript 对象的键都是字符串类型,值可以是任意数据类型。上述 person 对象一共定义了 6 个键值对,其中每个键又称为对象的属性,例如,person 的 name 属性为’Bob’,zipcode 属性为 null。
要获取一个对象的属性,我们用对象变量.属性名的方式:
person.name; // 'Bob'
person.zipcode; // null
如果我们要检测 xiaoming 是否拥有某一属性,可以用 in 操作符:
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
'name' in xiaoming; // true
'grade' in xiaoming; // false
不过要小心,如果 in 判断一个属性存在,这个属性不一定是 xiaoming 的,它可能是 xiaoming 继承得到的。
要判断一个属性是否是 xiaoming 自身拥有的,而不是继承得到的,可以用 hasOwnProperty() 方法:
var xiaoming = {
name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false
strict 模式
JavaScript 在设计之初,为了方便初学者学习,并不强制要求用 var 申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过 var 申明就被使用,那么该变量就自动被申明为全局变量:
i = 10; // i现在是全局变量
在同一个页面的不同的 JavaScript 文件中,如果都不用 var 申明,恰好都使用了变量 i,将造成变量 i 互相影响,产生难以调试的错误结果。
使用 var 申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内(函数的概念将稍后讲解),同名变量在不同的函数体内互不冲突。
为了修补 JavaScript 这一严重设计缺陷,ECMA 在后续规范中推出了 strict 模式,在 strict 模式下运行的 JavaScript 代码,强制通过 var 申明变量,未使用 var 申明变量就使用的,将导致运行错误。
启用 strict 模式的方法是在 JavaScript 代码的第一行写上:
'use strict';
Map 和 Set
Map 和 Set 是 ES6 标准新增的数据类型,请根据浏览器的支持情况决定是否要使用。
Map
Map 是一组键值对的结构,具有极快的查找速度。
如果用 Map 实现,只需要一个 “名字”-“成绩” 的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用 JavaScript 写一个 Map 如下:
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
初始化 Map 需要一个二维数组,或者直接初始化一个空 Map。Map 具有以下方法:
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
由于一个 key 只能对应一个 value,所以,多次对一个 key 放入 value,后面的值会把前面的值冲掉。
Set
Set 和 Map 类似,也是一组 key 的集合,但不存储 value。由于 key 不能重复,所以,在 Set 中,没有重复的 key。重复元素在 Set 中自动被过滤。add(key) , delete(key)
iterable
Array、Map 和 Set 都属于 iterable 类型,具有 iterable 类型的集合可以通过新的 for … of 循环来遍历。
用 for … of 循环遍历集合,用法如下:
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
console.log(x);
}
for (var x of s) { // 遍历Set
console.log(x);
}
for (var x of m) { // 遍历Map
console.log(x[0] + '=' + x[1]);
}