数组的解构
概念:在ES6中可以使用 [变量1,变量2,...] 的形式按照一定的规则(下标匹配模式)从数组中提取对应的值
语法:
// ES5
let arr = ['广东省','广州市','珠吉路']
let province = arr[0]
let city = arr[1]
let street = arr[2]
// ES6 数组解构
let [province, city, street] = ['广东省','广州市','珠吉路']
// 下标相等的变量会与数组中相同下标项进行匹配
注意:
- 数组的解构可以有缺省值
let [, city, street] = ['广东省', '广州市', '珠吉路']
console.log(city, street) // '广州市' '珠吉路'
- 数组的结构允许嵌套解构
let [[f,b], ,arr] = [['foo','bar'],1,[1,2,3]]
console.log(f, b, arr) // 'foo' 'bar' [1,2,3]
- 匹配不到的将会返回undefined
let [, city, street, test] = ['广东省', '广州市', '珠吉路']
console.log( test) // undefined
- 解构支持默认值
let [, city, street, test = '42号'] = ['广东省', '广州市', '珠吉路']
console.log( test) // 42号
对象的解构
概念:在ES6中对象也可以按照一定的规则(key匹配模式)从对象中提取对应的值
语法:
let {id, name, artist} = {
id: 347230,
name: "海阔天空",
artist: "Beyond",
album: "海阔天空",
duration: 326000,
mark: 8192
}
console.log(id, name, artist) // 347230 "海阔天空" "Beyond"
注意:
在对象解构中,变量的顺序不会影响匹配的属性值。但是必须保证匹配的变量名一定要和与指定对象的key一致。
对象的解构中,变量名可以自定义。修改解构赋值键值对value名称就好了。
其实对象的解构就是左边解构对象匹配右边对象数据的key。将右边对应key的value值赋值给左边结构对象 value 变量。
因为ES6中对象key与value相同时 可以简写为 {key} 等价于 {key:key}
let { name: musicName, artist: artist, id: id} = {
id: 347230,
name: "海阔天空",
artist: "Beyond",
album: "海阔天空",
duration: 326000,
mark: 8192
}
console.log(id, musicName, artist)
- 匹配不到的属性将会返回undefined
let { time } = {
id: 347230,
name: "海阔天空",
artist: "Beyond",
album: "海阔天空",
duration: 326000,
mark: 8192
}
console.log(time) // undefined
- 对象的结构同样支持嵌套解构
let {id, artists: [a1, a2], artists} = {
id: 347230,
name: "舒克贝塔",
artists: [{
name: '舒克'
},
{
name: '贝塔'
}
],
duration: 326000,
mark: 8192
}
console.log(id) // 347230
console.log(a1) // {name: '舒克'}
console.log(a2) // {name: '贝塔'}
console.log(artists) // [{name: '舒克'}, {name: '贝塔'}]
5.对undefined再进行结构将会报错
let {id: {name}} = {
id: 347230,
name: "舒克贝塔",
duration: 326000,
mark: 8192
}
console.log(name) // undefined
let {id: { name: {a} }} = { // Error Cannot read property 'a' of undefined
id: 347230,
name: "舒克贝塔",
duration: 326000,
mark: 8192
}
展开运算符 (...)
概念:ES6提供了展开运算符,功能展开数组或者对象(去除[] 或者 {})
语法:
let arr = [1,2,3,4]
let arr1 = [...arr, 7] // [1,2,3,4,7]
let person = { name: '小明', age: 18}
let newPerson = {...person, address: 'gz'} // { name: '小明', age: 18, address: 'gz'}
<center>「课堂练习」</center>
分别使用ES5、ES6实现在不修改原数组的情况选返回添加指定项的新数组
要求:1. 分别使用ES5和ES6的方法实现下面功能
2. 创建一个函数pushArr
3. 函数接受两个参数 参数一需要添加新的一项数组 参数二 新添加的项
4. 要求不能修改原数组, 返回一个原函数添加指定项后新的数组
部分代码:
let arr = [1, 2, 3, 4]
function pushArr(arr, item) {
/*TODO: 补充代码*/
}
let newArr = pushArr(arr, 77)
console.log(arr) // [1,2,3,4]
console.log(newArr) // [1, 2, 3, 4, 77]
注意:
- 使用对象的展开运算符给对象添加新的属性或实现对象的合并,如果出现相同的属性,后者将会替换前者。
let obj = {
name: '小明',
age: 18
}
let obj1 = {
age: 19,
address: 'gz'
}
console.log({...obj, ...obj1, address: 'sz'})
/*输出结果 {address: "sz",age: 19,name: "小明"} */
- 在解构中...支持剩余(rest)运算
let [a, b, ...c] = [1, 2, 3, 4, 5]
// a 1
// b 2
// c [3, 4, 5]
let {name, ...otherDetail} = {
name: '小明',
age: 18,
address: 'gz',
hobby: []
}
// name '小明'
// otherDetail { age: 18, address: 'gz', hobby: []}
- 字符串是一个特殊的数组,所以也可以使用展开运算符
[...'hello'] // ['h', 'e', 'l', 'l', 'o']
- 解构,展开运算符, rest运算都可以应用在函数的参数上
// 形参使用解构直接获取对象中需要用到的属性
function sayHello({name,age,city,...otherDetail} ) {
console.log('你好!我叫' + name+ '今年'+age+'岁' + ',来自' + city)
console.log(otherDetail)
}
let p = {
name: '小明',
age: 25,
city: '深圳',
hobby: [],
married: false
}
sayHello(p)
// 数组使用展开运算符向函数传递实参
function add(x, y) {
console.log(x + y)
}
let arr = [8, 17]
add(...arr)
ES6 对 Array 新增 API
map
概念:遍历当前数组生成一个新的数组
语法:map会接受一个遍历当前数组时都会执行一次的函数作为参数,该函数的返回值会作为新数组的对应下标值的数组项。该函数接收两个参数。
- 参数一 遍历数组当前的项的值
- 参数二 遍历数组当前的项的下标
let ages = [12, 14, 18, 13, 25]
let newAges = ages.map(function (item, index) {
if(item >= 18) {
return '成年'
}
return "未成年" // return 会返回新数组每一项的值
})
console.log( newAges) // ["未成年", "未成年", "成年", "未成年", "成年"]
console.log( ages) // [12, 14, 18, 13, 25]
filter
概念:遍历当前数组生成一个过滤后的新的数组
语法:filter会接受一个回调函数作为参数,每次遍历时,该函数都会被触发,该函数返回一个布尔值当值为真时保留数组当前项,否则则过滤。该函数接受两个参数。
- 参数一 遍历数组当前的项的值
- 参数二 遍历数组当前的项的下标
let ages = [12, 14, 17, 23, 18, 13, 25]
let newArr = ages.filter(function(item,index) {
if(item % 2 === 0) {
return true // 保留
}else {
return false // 删除
}
})
console.log(newArr)
from
概念:方法从一个类似数组或可迭代对象遍历生成一个新数组
语法:Array.from(arr[, mapFunc, mapThis])
- 参数一 需要遍历数组对象
- 参数二 一个遍历当前数组时都会执行一次的函数作为参数,该函数的返回值会作为新数组的对应下标值(可选)。该函数接受两个参数
- 参数一: 当前项的值
- 参数二: 当前项的下标
- 参数三 指定参数二内部的this (可选)
let arr = [1,2,3,4]
let cat = {
name: '小白',
age: 2
}
let newArr1 = Array.from(arr, function(item, index){
// item 数组的每一项的值
// index 数组每一项的下标
console.log(index, this)
return item * 3
}, cat) // 参数三是 参数二方法中的this
console.log(newArr1) // [3,6,9,12]
Array.from('foo');
// [ "f", "o", "o" ]
*of
概念:方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
语法:
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of(undefined); // [undefined]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
Array(undefined); // [undefined]
*copyWithin
概念:方法用于从数组的指定位置拷贝元素到数组的另一个指定位置中。该方法会修改原数组
语法:copyWithin(target[, start[, end]])
- 参数一 指定替换拷贝数组的下标位置
- 参数二 (可选)拷贝的起始位置 默认 0
- 参数三 (可选)替换的长度,默认是开始替换项的到数组最后一项的长度
[1,2,3,4,5,6].copyWithin(2,0) // [1,2,1,2,3,4]
[1,2,3,4,5,6].copyWithin(3,1,2) // [1,2,3,2,5,6]
find
概念:方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
语法:array.find(mapfuc)
- 参数一 find遍历数组每一项时都会调用一次该方法。该方法接收两个参数(当前项的值,当前项的下标)
let array = [0,12,22,55,44]
console.log(array.find((item,index) => item >= 18))
let todos = [{
id: 1,
text: '学习es6',
completed: false
},
{
id: 2,
text: '学习vue',
completed: true
},
{
id: 3,
text: '学习react',
completed: false
},
{
id: 4,
text: '学习js',
completed: false
},
]
console.log(todos.find(item => item.id === 2)) // {id: 2,text: '学习vue',completed: true}
findIndex
概念:方法返回数组中满足提供的测试函数的第一个元素的下标。否则返回 -1。
语法:array.findIndex(mapfunc)
参数一:mapfunc遍历数组每一项时都会调用一次该方法。该方法接收两个参数(当前项的值,当前项的下标)
let array = [0,12,22,55,44]
console.log(array.find((item,index) => item >= 18)) // 2
let todos = [{
id: 1,
text: '学习es6',
completed: false
},
{
id: 2,
text: '学习vue',
completed: true
},
{
id: 3,
text: '学习react',
completed: false
},
{
id: 4,
text: '学习js',
completed: false
},
]
console.log(todos.find(item => item.id === 2)) // 1
includes
概念:includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
语法:
const array1 = [1, 2, 3];
console.log(array1.includes(2)); // true
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat')); // true
console.log(pets.includes('at')); // false
reduce
概念:reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
语法:reducer(mapFunc)
- 参数一:遍历当前数组每一项时都会触发函数,该函数接收两个参数(参数一 上一次执行该函数的返回值, 参数二 当前项的值)
- 参数二:initalValue reduce的初始值
let price = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(price.reduce(function (reduce, item) {
return item + reduce
})) // 55
let todos = [{
id: 1,
text: '学习es6',
completed: false
},
{
id: 2,
text: '学习vue',
completed: false
},
{
id: 3,
text: '学习react',
completed: true
},
{
id: 4,
text: '学习js',
completed: false
},
]
todos.reduce((prevCount, item) => {
if (!item.completed) {
return prevCount + 1
}
return prevCount
}, 0)
*fill
概念:fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
语法:fill(val [,start [,end]])
- 参数一 指定填充的值
- 参数二 填充的起始位置 可选
- 参数三 填充的结束位置,不包括结束位置 可选
[1,2,3,4,5].fill(7) // [7,7,7,7,7]
[1,2,3,4,5].fill(7, 2) // [1,2,7,7,7]
[1,2,3,4,5].fill(7, 2, 4) // [1,2,7,7,5]
*其他的Array API:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
对象的简洁写法
概念:ES6允许在对象大括号内键值对同名的情况下简写成一个key值,如果key的值为普通函数可以简写为 key(){}的形式省略function关键字。
语法:
let name = '小明'
let age = 18
let obj = {
name, // 等价于 name: name
age, // 等价于 age
sayHello() { // 等价于 sayHello: function(){}
console.log('123')
}
}
对象的动态键名
概念:ES6允许在对象大括号中使用[js表达式的形式]让对象的key属性成为动态键名
语法:
let key = 'currentKey'
let obj = {
[key]: 123, // currentKey: 123
[key.split('').reverse().join('')]: 1, // yeKtnerruc: 1
sayHello() {
console.log('123')
}
}
字符串的模板语法
概念:ES6新增了一个 使用模板字符串语法对字符串进行增强,简化了一些复杂的字符串拼接
语法:模板字符串使用反引号 `配合${js表达式}语法`
let str = `你好!我叫${name}。明年${age+1}岁,来自${city}市。`
//等价于
let str = '你好!我叫' + name + '。明年' + (age + 1) + '岁' + ',来自' + city+'市。')
注意:模板字符串支持换行,输出的字符串会包含换行符
let str = `hello
world`