# 流程控制
# 遍历数据
数据示例
const user = { name: "liang", age: "18" }
const coder = ['html', 'css', 'js', 'php']
1
2
3
2
3
for in 循环是为了遍历对象而设计的, 但也可以遍历数组
for (const key in user) {
console.log(key, user[key])
}
for (const key in coder) {
console.log(key, coder[key])
}
1
2
3
4
5
6
7
2
3
4
5
6
7
for of 循环是专门用于遍历数组的, 无法获取数组下标, 且不能遍历对象
for (const item of coder) {
console.log(item)
}
1
2
3
2
3
Array.forEach() 方法遍历数组, 该方法没有返回值
coder.forEach((item, index, array) => {
// item 数组元素
// index 可选,数组下标
// array 可选,整个数组
console.log(item, index, array)
})
1
2
3
4
5
6
2
3
4
5
6
Array.map() 方法适用于遍历数组且需要改变数组值的情况,不会改变原数组,返回一个新数组
const array = coder.map(item => {
return item += ' _666'
})
1
2
3
2
3
# 展开语法
数组中的展开语法
const arr = [1, 2, 3]
const spread = [...arr, 4, 5] // [1, 2, 3, 4, 5]
1
2
2
对象中的展开语法 (属性重名时,后面的值会自动覆盖前面的)
const user = { name: 'liang', weight: 70 }
const info = { ...user, weight: 68, height: 180 }
console.log(info) // {name: 'liang', weight: 68, height: 180}
1
2
3
2
3
函数参数的展开语法
function spread(...args) {
console.log(...args)
}
spread() // args []
spread(1) // args [1]
spread(1, 2, 3) // args [1, 2, 3]
1
2
3
4
5
6
2
3
4
5
6
# 对象拷贝
示例数据
const user = { name: 'liang', age: 23 }
const profile = { name: 'liang', info: { age: 23, weght: 130 } }
1
2
2
# 浅拷贝
浅拷贝: 只是拷贝了基本类型的数据,而引用类型的数据,复制后还会发生引用
# 深拷贝
数据示例
const user = {
name: 'liang',
info: { age: 23 },
array: ['html', 'css', 'javascript'],
show(name) {
return `${name} call show method`
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
深拷贝对象-迭代递归法
// 深拷贝对象
function copy(object) {
let data = object instanceof Array ? [] : {}
for (const [key, value] of Object.entries(object)) {
data[key] = typeof value == 'object' ? copy(value) : value;
}
return data
}
// 拷贝对象
const profile = copy(user)
// 修改通过拷贝得到的变量不会影响原数据
profile.name = 'zhang'
profile.info.age = 18
profile.array.push('profile push data')
profile.show = () => 'profile update show method'
// 查看结果
console.log(user)
console.log(profile)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 解构赋值
# 数组解构
数组解构接收顺序不能变,不想接收的数组元素可以使用 ,
跳过
let [, age, work] = ['liang', '23', 'coder', 'php']
1
# 对象解构
对象解构接收的属性顺序没有要求
const { name, age: a } = { name: 'liang', age: 23, work: 'coder' }
1
多层对象的解构
let user = {
name: "liang",
info: {
weight: 65,
height: 135,
},
};
let { name, info: { weight: w, height } } = user
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
应用场景: 合并配置项
// 默认配置
const config = { url: "", method: "get", data: {} }
// 用户自定义配置
const params = { url: "/user/getProfile", method: "post", data: { id: 1 } }
// 方案一: 使用展开语法合并配置
const spread = { ...config, ...params }
// 方案二: 使用 Object.assign() 合并配置
// 初始化目标对象
const target = {}
// Object.assign(target, ...sources)
// 参数: target 目标对象 sources 源对象; 返回值: 目标对象
Object.assign(target, config, params)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 解构默认值
数组解构默认值
let [name, blog, age = 23] = ['liang', 'www.itqaq.com']
1
对象解构默认值
let { name, blog = 'www.itqaq.com' } = { name: "liang" };
1
# 高阶函数
数据
const data = [
{ name: "brede", score: 56 },
{ name: "maria", score: 75 },
{ name: "honey", score: 85 },
{ name: "liang", score: 90 },
];
1
2
3
4
5
6
2
3
4
5
6
# filter
Array.filter()
方法用于过滤数组元素,该方法会遍历数组所有元素,只保留满足条件的元素。
const result = data.filter((item) => item.score > 85);
1
Array.filter()
方法的完整写法
// item 当前循环的数组元素
// index 可选,当前循环的数组下标
// array 可选,整个数组数据
const result = data.filter(function (item, index, arr) {
// this 85
// filter 方法要使用第二个参数,第一个参数不能使用箭头函数,否则 this 的值是错的
return item.score > this;
}, 85);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# some
Array.some()
方法用于检测数组中的元素是否满足指定条件。
该方法会依次执行数组中的元素,如果有一个元素满足条件,则表达式直接返回 true
,剩余的元素不再检测;如果没有满足条件的元素,则返回 false
使用示例: 检测学生的分数中有没有大于 70 的
const result = data.some((item) => item.score > 70); // true
1
Array.some()
方法的完整写法
const result = data.some(function (item, index, arr) {
// item 当前循环的数组元素
// index 可选,当前循环的数组下标
// array 可选,整个数组数据
console.log([item, index, arr]);
// this 是 some 方法第二个参数的值
// 特别注意: 此时 some 方法的第一个参数不能是箭头函数,否则 this 的值是错的
return item.score > this;
}, 70);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# reduce
Array.reduce()
可以为数组中的每一个元素依次执行回调函数,并且可以保留上一次的回调结果
遍历数组元素,获取数组元素的某个属性之和
const result = data.reduce((total, item) => total + item.score, 0);
1
Array.reduce()
完整写法
// 初始值,也就是 total 第一次循环时的值
// 初始值是可选参数,省略时 total 值是第一个数组元素,并且 reduce 会跳过第一个索引,从第二个数组元素开始循环
const initialValue = 0;
const result = data.reduce((total, item, index, arr) => {
// 省略 initialValue 时,可以这样处理使其结果正确,但是不推荐,还是设置初始值更好
// if (index == 1) {
// total = total.score;
// }
return total + item.score;
}, initialValue);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Object 对象
数据示例
const user = { name: 'liang', age: 18 }
1
# getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor()
方法用于获取对象的自有属性的属性描述,又称为属性特征
// value 属性值
// writable 可写的
// enumerable 属性是否可以通过 for-in 访问属性,或通过 Object.keys() 获取
// configurable 代表是否能通过 delete 删除属性从而重新定义属性
// {value: 'liang', writable: true, enumerable: true, configurable: true}
const desc = Object.getOwnPropertyDescriptor(user, 'name')
// 获取所有自有属性的属性特征
Object.getOwnPropertyDescriptors(user)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9