因为感觉在操作上还蛮常用到 array
及 object
的各种方法,所以这篇就来说说 JavaScript 中 array
与 object
的各常用方法,以及 for in
和 for of
。
在 JavaScript 中,当你使用
typeof [1, 2, 3]
会出现
"object"
没错,在 JavaScript 中 array
其实也是 object
。
所以在判别两者时,不能使用 typeof
,而要使用 Array.isArray()
。
// true
Array.isArray(["Charlie", "the", "Unicorn"]);
// false
Array.isArray({
type: "Unicorn",
name: "Charlie"
});
我们每个方法都使用以下阵列做示范:
// 先做一个可怜的白老鼠阵列
let students = ["Jacob", "Pascal", "Jack"];
请想成每个试验前都重新变成以上状态。
students.push("Jeromy");
// ["Jacob", "Pascal", "Jack", "Jeromy"]
students.push("Eric", "Peter");
// ["Jacob", "Pascal", "Jack", "Jeromy", "Eric", "Peter"]
let lastOne = student.pop()
// ["Jacob", "Pascal", "Jack", "Jeromy", "Eric"]
// lastOne: "Peter"
push
会在阵列後方加上东西,可以一次加上多项东西。
pop
则会移除阵列最後方的一个东西并回传该东西。
students.unshift("Jeromy");
// ["Jeromy", Jacob", "Pascal", "Jack"]
students.unshift("Eric", "Peter");
// ["Eric", "Peter", "Jeromy", "Jacob", "Pascal", "Jack"]
let firstOne = student.shift()
// ["Peter", "Jeromy", "Jacob", "Pascal", "Jack"]
// firstOne: "Eric"
unshift
会在阵列前方加上东西,可以一次加上多项东西。 值得注意的是,加上多项东西时,它们在阵列中的位置会与传入的顺序相同。
shift
则会移除阵列最前方的一个东西并回传该东西。
let firstTwo = students.slice(0, 2);
// firstTwo: ["Jacob", "Pascal"]
let secondStu = students.slice(1, 2);
// secondStu: ["Pascal"]
let removed = students.splice(0, 1);
// students: ["Pascal", "Jack"]
// removed: ["Jacob"]
students.splice(0, 1, ...removed);
// students: ["Jacob", "Jack"]
slice
会自第一个参数的位置开始至第二个参数的位置前浅拷贝并回传。不会修改原阵列!
array.slice(start, ?end) // end 未指定会到底
splice
会自第一个参数的位置开始删除第二个参数数量的元素,再加上後方参数至该位置。会修改原阵列!
array.splice(start, delCount, add1, add2, ...)
let moreStu = ["Peter", "Eric", "Jeromy"];
students = students.concat(moreStu);
// students: ["Jacob", "Pascal", "Jack", "Peter", "Eric", "Jeromy"]
concat
可以合并多阵列,但记得不会修改原阵列!
array.concat(addArray1, addArray2, ...)
students.sort((a, b) => b.length - a.length);
// ["Pascal", "Jacob", "Jack"]
students.reverse();
// ["Jack", "Jacob", "Pascal"]
sort
用来排序阵列,其参数为一个「比较函式」,其有参数 a, b 代表两个被比较的元素,如果回传值大於 0 则 b 排在 a 前,反之,a 排在 b 前。此方法直接修改原阵列!
可以想成如果大於 0 则 b 超 a 车跑到前面去
reverse
则是将阵列反过来。此方法直接修改原阵列!
students.forEach((name, idx) => {
console.log(idx, name);
});
// Console:
// 0 "Jacob"
// 1 "Pascal"
// 2 "Jack"
students = students.map(name => {
return "Student " + name;
});
// ["Student Jacob", "Student Pascal", "Student Jack"]
forEach
用来遍历阵列的值,并对每项进行操作。不修改原阵列且没有回传值。
array.forEach((value, index, array) => {
// do something
})
// 没有回传值
map
也是用来遍历阵列的值,并对每项进行修改。不修改原阵列但会回传经修改过的阵列。
array.map((value, index, array) => {
// do something
// and return new value
})
// 回传修改後的阵列
let namesWithJ = students.filter(name => name.includes("J"));
// namesWithJ: ["Jacob", "Jack"]
let firstNameWithJ = students.find(name => name.includes("J"));
// firstNameWithJ: "Jacob"
filter
用来过滤阵列中符合条件的值,并回传该符合条件的阵列。如果判别函式回传 true
就是符合,反之则是不符合。不修改原阵列。
array.filter((value, index, array) => {
// 如果符合条件回传 true 反之回传 false
})
find
与 filter
很像,但只回传第一个符合条件的值。不修改原阵列。
array.find((value, index, array) => {
// 如果符合条件回传 true 反之回传 false
})
let str = students.reduce((accu, name, idx) => {
return accu + name + ((idx !== students.length - 1) ? ", " : ".");
}, "Students: ");
// str: "Students: Jacob, Pascal, Jack."
let numbers = [[1,2], [3,4]];
let flatted = numbers.flat();
// flatted: [1, 2, 3, 4]
let str2 = students.join(", ");
// str2: "Jacob, Pascal, Jack"
reduce
flat
join
都是用来减少阵列的维度。三者都不会修改原阵列。
reduce
应该是三者灵活度最高的,flat
跟 join
可以当 shorthand 来用。
array.reduce((accumulator, value, index, array) => {
// 一项一项的把东西合并到 accumulator
// 记得要回传东西,做为新的 accumulator
}, initialAccumulator)
flat
用来拆高维阵列,它可以放一个参数表示拆的深度。
array.flat(depth); // depth 代表要拆的深度
join
用来把阵列变字串,同时可指定中间插入的字串。
array.join(str) // 每项元素间会加上 str
split
就是用来反向操作 join
的,回传一分割後的阵列。
string.split(str) // str 会用来作为刀子切 string
关於物件也有几个有用的工具。请注意,它们都是 static 所以需要在前面加上 Object.
。
// 白老鼠物件
let charlie = {
type: "unicorn",
age: 1000
}
let entries = Object.entries(charlie);
// entries: [
// ["type", "unicorn"],
// ["age", 1000]
// ]
let keys = Object.keys(charlie);
// keys: ["type", "age"]
let values = Object.values(charlie);
// values: ["unicorn", 1000]
entries
keys
values
都是用来将物件转换成阵列用的,因为阵列有比较多好操作的方法。三者都不会修改原物件。
let fix = {
age: 500,
mood: ["angry", "tired"]
};
Object.assign(charlie, fix);
// charlie: {
// type: "unicorn",
// age: 500,
// mood: ["angry", "tired"]
// }
assign
用来复制物件内容,第一个参数是目标物件,後方参数为一或多个物件,其值会复制至目标物件。它会修改目标物件,且回传目标物件!
Object.assign(target, source1, source2, ...); // target 会被修改
// 不想直接修改 target? 把第一个位置放 {} 就好了
let newThings = Object.assign({}, target, source1, source2, ...)
for
也常常用来遍历阵列或物件。
直接用阵列长度及 i
来遍历。
let arr = ["Ha", "Haha", "Lalala"];
for(let i = 0; i < arr.length; i++) { // arr.length === 3
console.log(i, arr[i]); // 0 "Ha" 1 "Haha" 2 "Lalala"
}
for of
也可以用来遍历阵列。
let arr = ["Ha", "Haha", "Lalala"];
for(const str of arr) {
console.log(str); // "Ha" "Haha" "Lalala"
}
for in
可以用於遍历物件的键 (key
)。
let charlie = {
type: "unicorn",
age: 1000
}
for(const key in charlie) {
console.log(key, charlie[key]);
}
以 9/17 12:00 ~ 9/18 12:00 文章观看数增加值排名
+592
Day 3 云端四大平台比较:AWS . GCP . Azure . Alibaba
+556
Day 1 无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
+456
Day 2 AWS 是什麽?又为何企业这麽需要 AWS 人才?
+454
Day 5 网路宝石:AWS VPC 架构 Routes & Security (上)
+442
Day 4 网路宝石:AWS VPC Region/AZ vs VPC/Subnet 关系介绍
+422
Day 6 网路宝石:AWS VPC 架构 Routes & Security (下)
+420
Day 7 网路宝石:【Lab】VPC外网 Public Subnet to the Internet (IGW) (上)
+396
Day 8 网路宝石:【Lab】VPC外网 Public Subnet to the Internet (IGW) (下)
+388
Day 9 运算宝石:EC2 重点架构
+386
Day 12 运算宝石:【Lab】EC2储存资源 EBS Volume 建立与使用 (上)
WOW!!
今天前十都是「无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题」系列!
看来大家都很爱 AWS,我是不是也该学学了?
<<: 【Day 5】机器学习基本功(三) --- Regression
>>: Android Studio初学笔记-Day3--RelativeLayout
if event.postback.data[0] == "专" and eve...
继上篇,我们拿到了一个AS Number及IPv6。我们接着就要开始去广播我们的网路啦!!! 首先,...
首先对本篇主题中的一些常见名词与讨论角度做基本的定义;建立共同的出发点以利文章阅读,并直接破题回答,...
Attribute vs Property attribute:属性在 HTML 会被称为 attr...
每一个动作都是函数 语法 A::install.packages("aa") ...