基本类型
string
、number
、boolean
、symbol
、null
和 undefined
。对象类型
{}
创建对象,例如:{name: "John", age: 30}
。JavaScript 中还有其他种类的对象,例如函数就是对象。在 JavaScript 中,我们通过在数字后附加字母 “e” 来缩短数字,并指定零的数量来计数:
let billion = 1e9; // 1 billion, literally: 1 and 9 zeroes
alert( 7.3e9 ); // 7.3 billions (7,300,000,000)
isFinite 和 isNaN
Infinite
(和 -Infinite
)是一个特殊的数值,比任何数值都大(小)。NaN
代表一个错误。字符串可以包含在单引号、双引号或反引号中:
let single = 'single-quoted';
let double = "double-quoted";
let backticks = `backticks`;
反引号允许我们通过 ${…}
将任何表达式嵌入到字符串中,另一个优点是它们允许字符串跨行:
function sum(a, b) {
return a + b;
}
alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.
let guestList = `Guests:
* John
* Pete
* Mary
`;
alert(guestList); // 客人清单,多行
其他不常见的“特殊字符”
在 JavaScript 中,字符串不可更改。改变字符是不可能的。
let str = 'Hi';
str[0] = 'h'; // error
alert( str[0] ); // 无法运行
通常的解决方法是创建一个新的字符串,并将其分配给 str
而不是以前的字符串。
let str = 'Hi';
str = 'h' + str[1]; // 字符串替换
alert( str ); // hi
第一个方法是 str.indexOf(substr, pos)。
它从给定位置 pos
开始,在 str
中查找 substr
,如果没有找到,则返回 -1
,否则返回匹配成功的位置。
let str = 'Widget with id';
alert( str.indexOf('Widget') ); // 0,因为 'Widget' 一开始就被找到
alert( str.indexOf('widget') ); // -1,没有找到,检索是大小写敏感的
alert( str.indexOf("id") ); // 1,"id" 在位置 1 处(……idget 和 id)
str.lastIndexOf(subStr, pos)
他从字符串的末尾开始搜索。
JavaScript 中有三种获取字符串的方法:substring
、substr
和 slice
。
${…}
中嵌入表达式。\n
这样的特殊字符或通过使用 \u...
来操作它们的 unicode 进行字符插入。[]
。slice
或 substring
。toLowerCase/toUpperCase
。indexOf
或 includes/startsWith/endsWith
进行简单检查。localeCompare
,否则将按字符代码进行比较。字符串还有其他几种有用的方法:
str.trim()
—— 删除字符串前后的空格 (“trims”)。str.repeat(n)
—— 重复字符串 n
次。创建一个空数组有两种语法:
let arr = new Array();
let arr = [];
数组可以存储任何类型的元素。
// 混合值
let arr = [ 'Apple', { name: 'John' }, true, function() { alert('hello'); } ];
// 获取索引为 1 的对象然后显示它的 name
alert( arr[1].name ); // John
// 获取索引为 3 的函数并执行
arr[3](); // hello
fruits.shift(); // 从前端取出一个元素
shift
操作必须做三件事:
0
的元素。1
改成 0
,2
改成 1
以此类推,对其重新编号。length
属性。数组里的元素越多,移动它们就要花越多的时间,也就意味着越多的内存操作。
pop
操作的动作:
fruits.pop(); // 从末端取走一个元素
let arr = ["Apple", "Orange", "Pear"];
for (let i = 0; i < arr.length; i++) {
alert( arr[i] );
}
let fruits = ["Apple", "Orange", "Plum"];
// 迭代数组元素
for (let fruit of fruits) {
alert( fruit );
}
在这里我们将每个元素转换为它的字符串长度:
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length)
alert(lengths); // 5,7,6
let arr = [ 1, 2, 15 ];
// 该方法重新排列 arr 的内容(并返回它)
arr.sort();
alert( arr ); // 1, 15, 2
数组方法备忘录:
添加/删除元素:
push(...items)
— 从结尾添加元素,pop()
— 从结尾提取元素,shift()
— 从开头提取元素,unshift(...items)
— 从开头添加元素,splice(pos, deleteCount, ...items)
— 从 index
开始:删除 deleteCount
元素并在当前位置插入元素。slice(start, end)
— 它从所有元素的开始索引 "start"
复制到 "end"
(不包括 "end"
) 返回一个新的数组。concat(...items)
— 返回一个新数组:复制当前数组的所有成员并向其中添加 items
。如果有任何items
是一个数组,那么就取其元素。查询元素:
indexOf/lastIndexOf(item, pos)
— 从 pos
找到 item
,则返回索引否则返回 -1
。includes(value)
— 如果数组有 value
,则返回 true
,否则返回 false
。find/filter(func)
— 通过函数过滤元素,返回 true
条件的符合 find 函数的第一个值或符合 filter 函数的全部值。findIndex
和 find
类似,但返回索引而不是值。转换数组:
map(func)
— 从每个元素调用 func
的结果创建一个新数组。sort(func)
— 将数组倒序排列,然后返回。reverse()
— 在原地颠倒数组,然后返回它。split/join
— 将字符串转换为数组并返回。reduce(func, initial)
— 通过为每个元素调用 func
计算数组上的单个值并在调用之间传递中间结果。迭代元素:
forEach(func)
— 为每个元素调用 func
,不返回任何东西。其他: – Array.isArray(arr)
检查 arr
是否是一个数组。
请注意,sort
,reverse
和 splice
方法修改数组本身。
Map 是一个键值对的集合,很像 Object
。但主要的区别是,Map
允许所有数据类型作为键。
主要的方法包括:
new Map()
– 创建 map。map.set(key, value)
– 根据键(key)存储值(value)。map.get(key)
– 根据键返回值,如果 map 中该键不存在,返回 undefined
。map.has(key)
– 如果键存在,返回 true
,否则返回 false
。map.delete(key)
– 移除该键的值。map.clear()
– 清空 mapmap.size
– 返回当前元素个数。 let map = new Map();
map.set('1', 'str1'); // 字符串作为 key
map.set(1, 'num1'); // 数字作为 key
map.set(true, 'bool1'); // 布尔值作为 key
// 还记得普通对象 Object 吗?它将会把所有的键转化为字符串类型
// 但是 Map 将会保留键的类型,所以下面这两个是不同的:
alert( map.get(1) ); // 'num1'
alert( map.get('1') ); // 'str1'
alert( map.size ); // 3
map.keys()
– 返回键的迭代器,map.values()
– 返回值的迭代器,map.entries()
– 返回 [key, value]
迭代器入口,for..of
循环会默认使用它。 let recipeMap = new Map([
['cucumber', 500],
['tomatoes', 350],
['onion', 50]
]);
// 迭代键(vegetables)
for (let vegetable of recipeMap.keys()) {
alert(vegetable); // cucumber, tomatoes, onion
}
// 迭代值(amounts)
for (let amount of recipeMap.values()) {
alert(amount); // 500, 350, 50
}
// 迭代键值对 [key, value]
for (let entry of recipeMap) { // 和 recipeMap.entries() 一样
alert(entry); // cucumber,500(等等)
}
Set
是一个值的集合,这个集合中所有的值仅出现一次。
主要方法包括:
new Set(iterable)
– 创建 set,利用数组来创建是可选的(任何可迭代对象都可以)。set.add(value)
– 添加值,返回 set 自身。set.delete(value)
– 删除值,如果该 value
在调用方法的时候存在则返回 true
,否则返回 false
。set.has(value)
– 如果 set 中存在该值则返回 true
,否则返回 false
。set.clear()
– 清空 set。set.size
– 元素个数。
let set = new Set();
let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
// 访客,一些用户来了多次
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);
// set 保证了值的唯一
alert( set.size ); // 3
for (let user of set) {
alert(user.name); // John(然后是 Pete 和 Mary)
}
我们可以使用 for..of
或者 forEach
来循环查看 set:
let set = new Set(["oranges", "apples", "bananas"]);
for (let value of set) alert(value);
// 和 forEach 相同:
set.forEach((value, valueAgain, set) => {
alert(value);
});
Map
—— 是一个键值对集合
和普通 Object
的区别:
size
属性。Set
—— 是一个包含不重复值的集合。
WeakMap
—— Map
的一个变体,仅允许对象作为键,并且当对象由于其他原因不可引用的时候将其删除。
size
属性,没有 clear()
方法,没有迭代器。WeakSet
—— 是 Set
的一个变体,仅存储对象,并且当对象由于其他原因不可引用的时候将其删除。
size/clear()
和迭代器。