2.1.let关键字
为了解决之前版本中 var
关键字存在存在着越域, 重复声明等多种问题, 在 ES6 以后推出 let
这个新的关键字用来定义变量
//声明变量
let a;
let b,c,d;
let e = 100;
let f = 123, g = 'hello javascript', h = [];
let 关键字用来声明变量,使用 let 声明的变量有几个特点:
-
不允许重复声明
var s = "王小二"; var s = "李小三"; let name = '王小二'; let name = '李小三'; // Uncaught SyntaxError: Identifier 'name' has already been declared
-
块儿级作用域
if else while for 语句 都可以定义代码块
// for(var i = 0;i < 5; i++){ // console.log(i) // } // console.log( "i:", i ) // i 越域 { let girl = '赵静子'; } console.log(girl); // Uncaught ReferenceError: girl is not defined
-
不存在变量提升
// console.log(s) // undefined // var s = "abc" // console.log(s) // abc console.log(song); //Uncaught ReferenceError: Cannot access 'song' before initialization let song = '最炫民族风'; console.log(song) // 不会再执行到这行
2.2. const 关键字
定义常量, 不能修改
//声明常量
const GOODS = '书包';
const 关键字用来声明常量,const 声明有以下特点
-
声明必须赋初始值
const A; // Uncaught SyntaxError: Missing initializer in const declaration
-
标识符一般为大写(潜规则, 不是必须的)
-
不允许重复声明
const GOODS = '书包'; const GOODS = '钢笔'; // Uncaught SyntaxError: Identifier 'GOODS' has already been declared
-
块儿级作用域
{ const NAME = '王小二'; } console.log(NAME); // Uncaught ReferenceError: NAME is not defined
-
值不允许修改
const BOOK = '三体'; BOOK = '西游记'; // Uncaught TypeError: Assignment to constant variable.
特别要注意 : 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
const TEAM = ['王小二','李小三']; TEAM.push('赵小四'); const STU = { name: '王小二', age: 18 } STU.name = '赵小四';
应用场景:声明对象类型使用const,非对象类型声明选择 let
2.3.变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
2.3.1.数组的解构赋值
const F4 = ['王小二','李小三','赵小四','张不开'];
// let wang = F4[0];
// let li = F4[1];
// let zhao = F4[2];
// let zhang = F4[3];
let [ wang, li, zhao, zhang ] = F4;
console.log(wang);
console.log(li);
console.log(zhao);
console.log(zhang);
2.3.1.1.可嵌套
let [a,[b,c]] = [1,[2,3]];
console.log(a,b,c);
2.3.1.2.解构默认值
let [h=2]=[3]; //[] [undefined]
console.info(h); // 3
let [i = 3, j = i] = [];
console.info(i,j); // 3 3
let [k = 3, l = k] = [1];
console.info(k, l); // 1 1
let [m = 3, n = m] = [1, 2];
console.log(m, n); // 1 2
2.3.1.3.剩余运算符
let [p, ...q] = [1,2,3];
console.log(p,q); // 1 [ 2, 3]
2.3.1.4.字符串
let [s1, s2, s3, s4, s5] = "hello";
console.log( s1, s2, s3, s4, s5 ); // h e l l o
2.3.2.对象的解构赋值
const STU = {
name: '王小二',
age: 18,
sayHello: function(){
console.log("Hello, 我是" + this.name);
}
};
// let name = STU.name
// let age = STU.age;
// let sayHello = STU.sayHello;
// let { name : name , age : age , sayHello : sayHello } = STU;
let { name, age, sayHello } = STU;
console.log(name);
console.log(age);
// console.log(sayHello);
sayHello();
// let { sayHello } = STU;
// sayHello();
// let { name : abc } = STU;
// console.log(abc)
2.3.2.1.解构默认值
let { h=2}={ h : 3 }; //[] [undefined]
console.info(h); // 3
let { i = 3, j = i } ={ };
console.info(i,j); // 3 3
let { k = 3, l = k } = { k : 1 };
console.info(k, l); // 1 1
let { m = 3, n = m } = { m : 1, n : 2 };
console.info(m, n); // 1 2
2.3.3.复杂解构
先定义对象
let wang = {
hobby: ['运动','美食','音乐'],
study:[
{ name: 'java', info:'啥都能干'},
{ name: 'HTML', info: '挺好学的'},
{ name: 'javascript', info: '也啥都能干'}
]
}
2.3.3.1.解构方式1
let { hobby, study } = wang;
console.log( hobby);
console.log( hobby[0] );
console.log( hobby[1] );
console.log( hobby[2] );
console.log( study );
console.log( study[0].name );
console.log( study[0].info );
2.3.3.2.解构方式2
one , two, three, java, html, js 才是解构出来的变量
let { hobby: [ one, two, three ] , study : [ java, html, js ] } = wang;
// console.log( hobby); // 使用报错 : Uncaught ReferenceError: hobby is not defined
console.log( one );
console.log( two );
console.log( three );
console.log(java.name);
console.log(html.info);
console.log( js )
console.log( js.name )
注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式
2.4.字符串优化
2.4.1.模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:
- 字符串中可以出现换行符
- 可以使用 ${xxx} 形式输出变量
2.4.1.1.定义字符串
let s = `我也是一个字
符
串
哦!`;
console.log(s, typeof s);
let str = `<ul>
<li>王小二</li>
<li>李小三</li>
<li>赵小四</li>
</ul>`;
console.log(str, typeof str);
2.4.1.2.输出变量
let zhao = '赵静子';
let out = `${zhao}是个大美女!!`;
console.log(out);
注意:当遇到字符串与变量拼接的情况使用模板字符串
2.4.1.3.插入函数结果
function fn() {
return "函数返回结果!";
}
let str = `调用函数得到结果: ${fn()}`;
console.log(str);
2.4.2.新增方法
-
startsWith()
:判断字符串是否以特定的字符开头。 -
endsWith()
:判断字符串是否以特定的字符结尾。 -
includes()
:判断字符串是否包含特定的字符。 -
repeat()
:重复生成指定次数的字符串。let str = "hello.vue"; console.log(str.startsWith("hello")); //true console.log(str.endsWith(".vue")); //true console.log(str.includes("e")); //true console.log(str.includes("hello")); //true let ss = str.repeat(3); //hello.vuehello.vuehello.vue console.log(ss)
-
( ES 10 )
trimStart()
和trimEnd()
let str = ' hello world '; console.log(str); // " hello world " console.log(str.trim() ); // "hello world" console.log(str.trimStart()); // "hello world " console.log(str.trimEnd()); // " hello world"
2.5. 数值扩展
2.5.1.Number新增方法
2.5.1.1.Number.EPSILON
Number.EPSILON 是 JavaScript 表示的最小精度
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
function equal(a, b){
if(Math.abs(a-b) < Number.EPSILON){
return true;
}else{
return false;
}
}
console.log(0.1 + 0.2 === 0.3);
console.log(equal(0.1 + 0.2, 0.3))
2.5.1.2.二进制和八进制
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。
let b = 0b1010; // 二进制
let o = 0o777; // 八进制
let d = 100; // 十进制
let x = 0xff; // 十六进制
console.log(x);
2.5.1.3.Number.isFinite()
Number.isFinite() 用来检查一个数值是否为有限的
console.log(Number.isFinite(100)); // true
console.log(Number.isFinite(100/0)); // false
console.log(Number.isFinite(Infinity)); // false
2.5.1.4.Number.parseInt() 与 Number.parseFloat()
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变。
console.log(Number.parseInt('5211314love')); // 5211314
console.log(Number.parseFloat('3.1415926神奇')); // 3.1415926
2.5.1.5.Number.isInteger
Number.isInteger() 用来判断一个数值是否为整数
console.log(Number.isInteger(5)); // true
console.log(Number.isInteger(2.5)); // false
2.5.2.Math新增方法
2.5.2.1.Math.sign
判断一个数到底为正数 负数 还是零
console.log(Math.sign(100)); // 1
console.log(Math.sign(0)); // 0
console.log(Math.sign(-20000)); // -1
2.5.2.2.Math.trunc
用于去除一个数的小数部分,返回整数部分。
console.log(Math.trunc(3.5)); // 3
2.5.2.3.( ES 7 )幂运算新写法
在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同
console.log(2 ** 10);//
console.log(Math.pow(2, 10));
2.5.3.( ES 11 ) BigInt
更大的数据范围, 只能是整数
//大整形
let n = 521n;
console.log(n, typeof(n)); // 521n 'bigint'
//函数
// let n = 123;
console.log(BigInt(n)); // 123n
console.log(BigInt(1.2)); // Uncaught RangeError: The number 1.2 cannot be converted to a BigInt because it is not an integer
//大数值运算
let max = Number.MAX_SAFE_INTEGER; // 9007199254740991
console.log(max); // 9007199254740991
console.log(max + 1); // 9007199254740992
console.log(max + 2); // 9007199254740993
console.log(BigInt(max)) // 9007199254740991n
console.log(BigInt(max) + BigInt(1)) // 9007199254740992n
console.log(BigInt(max) + BigInt(2)) // 9007199254740993n
2.6. ( ES 9 ) 正则表达式
2.6.1.( ES 9 ) 命名捕获组
同时 匹配多个信息, 之前的处理方式
//声明一个字符串
let str = '<a href="http://www.baidu.com">百度</a>';
//提取 url 与 『标签文本』
const reg = /<a href="(.*)">(.*)<\/a>/;
//执行
const result = reg.exec(str);
console.log(result);
// 输出:
// [
// '<a href="http://www.baidu.com">百度</a>',
// 'http://www.baidu.com',
// '百度',
// index: 0,
// input: '<a href="http://www.baidu.com">百度</a>',
// groups: undefined
// ]
console.log(result[1]); // http://www.baidu.com
console.log(result[2]); // 百度
ES 9 允许命名捕获组使用符号 ?<name>
,这样获取捕获结果可读性更强
let str = '<a href="http://www.baidu.com">百度</a>';
//分组命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result)
// 输出:
// [
// '<a href="http://www.baidu.com">百度</a>',
// 'http://www.baidu.com',
// '百度',
// index: 0,
// input: '<a href="http://www.baidu.com">百度</a>',
// groups:{ text:"百度", url:"http://www.baidu.com" },
// length : 3
// ]
console.log(result.groups.url); // http://www.baidu.com
console.log(result.groups.text); // 百度
2.6.2.( ES 9 )反向断言
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。
//声明字符串
// let str = '电话号码13123456789年龄23岁';
let str = '电话号码13987654321年龄45岁';
//正向断言
const reg1 = /\d+(?=岁)/;
const result1 = reg1.exec(str);
console.log(result1);
//反向断言
const reg2 = /(?<=年龄)\d+/;
const result2 = reg2.exec(str);
console.log(result2);
2.6.3.( ES 9 )dotAll 模式
正则表达式中点.
匹配除回车外的任何单字符,标记s
改变这种行为,
允许行终止符出现
//dot . 元字符 除换行符以外的任意单个字符
let str = `
<ul>
<li>
<a>热辣滚烫</a>
<p>上映日期: 2024-02-10</p>
</li>
<li>
<a>你好, 李焕英</a>
<p>上映日期: 2021-02-12</p>
</li>
</ul>`;
//声明正则
// const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
//执行匹配
// const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]});
}
//输出结果
console.log(data);
2.6.4.( ES 11 ) String.prototype.matchAll
得到 正则批量匹配结果
let str = `<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//声明正则
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
//调用方法
const result = str.matchAll(reg);
// for(let v of result){
// console.log(v);
// }
const arr = [...result];
console.log(arr);
2.7.数组Array
扩展
在 ES6(ECMAScript 2015)中,JavaScript 对 Array
对象进行了多个重要扩展和改进,以增强数组操作的便利性和性能。
2.7.1.主要的 新特性
2.7.1.1.扩展运算符 (...
)
可用于解构赋值、复制数组以及将数组转换为参数序列。
let arr1 = [1, 2, 3];
let arr2 = [...arr1]; // 复制数组:[1, 2, 3]
let combined = [0, ...arr1, 4]; // 合并数组:[0, 1, 2, 3, 4]
function logArgs(...args) {
console.log(args);
}
logArgs(...arr1); // 输出:[1, 2, 3]
2.7.1.2.Array.from()
将类数组对象或可迭代对象转换为真正的数组。
let arrayLike = { 0: 'a', 1: 'b', length: 2 };
let arr = Array.from(arrayLike); // 转换为:['a', 'b']
2.7.1.3.Array.of()
根据传入的参数创建一个新数组。
let arr = Array.of(1, 2, 3); // 创建:[1, 2, 3]
2.7.1.4.( ES 7 )Array.prototype.includes()
检查数组是否包含某个指定的值。
let arr = [1, 2, 3];
console.log(arr.includes(2)); // 输出:true
2.7.1.5…参数与展开语法在数组方法中的应用
例如,在 Math.max()
和 Math.min()
中可以使用剩余参数来替代 apply()
方法。
let maxNumber = Math.max(...arr); // 获取数组中的最大值
2.7.1.6.fill()
填充数组的方法,用给定值填充数组的一部分或全部。
let filledArr = new Array(5).fill('hello');
console.log(filledArr); // 输出:['hello', 'hello', 'hello', 'hello', 'hello']
2.7.1.7.( ES 10 ) flat() / flatMap()
将嵌套数组拉平为一维数组。
let arrs = [ [1,2,3], [4,5,6,7], [8,9,10] ];
console.log(arrs.length) //3
// 将嵌套数组拉平为一维数组。
let arrs1 = arrs.flat()
console.log(arrs1.length) // 10
console.log(arrs1) // 10
// 先对数组中的每个元素执行映射函数,然后将结果拉平为一维数组。
let arrs2 = arrs.flatMap( item => Math.max(...item) )
console.log(arrs2)
2.7.1.8.copyWithin()
在数组内部的一个位置复制数组的一部分到另一个位置。
let copyArr = [1, 2, 3, 4, 5];
copyArr.copyWithin(0, 3); // 把从下标3开始的元素复制到下标0开始的位置:[4, 5, 3, 4, 5]
2.7.1.9.包含includes()
// 参数1:包含的指定值
console.log( [1, 2, 3].includes(1) ); // true
// 参数2:可选,搜索的起始索引,默认为0
console.log( [ 1, 2, 3 ].includes(1, 2) ); // false
// NaN 的包含判断
console.log( [ 1, NaN, 3].includes(NaN) ); //true
2.7.2.结合箭头函数
2.7.2.1.map()
map()
方法对数组中的每个元素执行给定的回调函数,并将回调函数的返回值组成一个新数组返回。
它可以用于对原始数组中的每个元素进行处理,并返回一个处理后的新数组。
let numbers = [1, 2, 3, 4, 5];
let squared = numbers.map(n => n * n); // 映射:[1, 4, 9, 16, 25]
2.7.2.2.reduce()
reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,
arr.reduce(callback,[initialValue])
callback () 的参数
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
let arr = [2, 40, -10, 6]
let result = arr.reduce( (a,b)=>{
console.log("上一次处理后:" + a);
console.log("当前正在处理:" + b);
return a + b;
},100 );
console.log(result)
// 运行结果
// 上一次处理后:100
// 当前正在处理:2
// 上一次处理后:102
// 当前正在处理:40
// 上一次处理后:142
// 当前正在处理:-10
// 上一次处理后:132
// 当前正在处理:6
// 138
2.7.2.3.filter()
方法用于过滤数组中的元素,返回满足给定条件的新数组。
它可以通过指定一个回调函数来筛选出需要的元素,该方法返回一个新数组。
// 筛选出数组中偶数
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // 输出:[2, 4, 6, 8]
// 从用户对象列表中筛选出年龄大于等于18岁的用户
let users = [
{ id: 1, name: '王小二', age: 20 },
{ id: 2, name: '李小三', age: 17 },
{ id: 3, name: '赵小四', age: 22 },
{ id: 4, name: '张不开', age: 16 }
];
let adults = users.filter(user => user.age >= 18);
console.log(adults);
// 输出:
// [
// { id: 1, name: '王小二', age: 20 },
// { id: 3, name: '赵小四', age: 22 }
// ]
// 筛选非空字符串
let strings = ['apple', '', '张不开', null, undefined , '123'];
let nonEmptyStrings = strings.filter(str => str && str.trim().length > 0);
console.log(nonEmptyStrings);
// 输出:['apple', '张不开', '123']
2.7.2.4.find()
find()
: 返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。
let arr = [ 1, 2, 3, 4, 5, 6]
let found = arr.find(item => item > 3); // 返回第一个大于3的元素
console.log( found )
let foundIndex = arr.findIndex(item => item > 3); // 返回第一个大于3的元素
console.log( foundIndex )
2.7.2.5.迭代器方法
entries()
, keys()
, values()
提供了迭代器接口。
let arr = [ 1, 2, 3, 4, 5, 6]
for (let [index, value] of arr.entries()) {
console.log(index, value);
}
2.8. 扩展Set
ES6 提供了新的数据结构 Set(集合)。
它类似于数组,但成员的值都是唯一的,
集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,
2.8.1.集合的常用属性和方法
-
size 返回集合的元素个数
-
add 增加一个新元素,返回当前集合
-
delete 删除元素,返回 boolean 值
-
has 检测集合中是否包含某个元素,返回 boolean 值
-
clear 清空集合,返回 undefined
//声明一个 空 set
let s = new Set();
let s2 = new Set(['王小二','李小三','赵小四','张小三','李小三']);
console.log(s2);
// //元素个数
console.log(s2.size);
// //添加新的元素
s2.add('刘小六');
s2.add('王小二')
console.log(s2);
// //删除元素
s2.delete('张小三');
console.log(s2);
// //检测
console.log(s2.has('赵小四'));
// //清空
// s2.clear();
// console.log(s2);
//
for(let v of s2){
console.log(v);
}
2.8.2.应用
let arr = [1,2,3,4,5,4,3,2,1];
//1. 数组去重
// let result = [...new Set(arr)];
// console.log(result);
//2. 交集 has()
let arr2 = [4,5,6,5,6];
// let result = [...new Set(arr)].filter(item => {
// let s2 = new Set(arr2);// 4 5 6
// if(s2.has(item)){
// return true;
// }else{
// return false;
// }
// });
// // let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
// console.log(result);
//3. 并集
// let union = [...new Set([...arr, ...arr2])];
// console.log(union);
//4. 差集
// let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
// console.log(diff);
2.9.对象Object优化
2.9.1.对象新的方法
2.9.1.1.( ES 8 ) 结构分析
-
Object.values()方法返回一个给定对象的所有可枚举属性值的数组
-
Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
//声明对象 const STU = { name : "王小二", study : ['java','html','js'] }; //获取对象所有的键 console.log(Object.keys(STU)); // ['name', 'study'] //获取对象所有的值 console.log(Object.values(STU)); // ['王小二', ['java', 'html', 'js']] //entries console.log(Object.entries(STU)); // [['name', '王小二'], ['study', ['java', 'html', 'js']]] //创建 Map const m = new Map(Object.entries(STU)); console.log(m.get('study'));
2.9.1.2.判断完全相等
// Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120));// true
console.log(Object.is(120, '120'));// false
console.log(Object.is(NaN, NaN));// true
console.log(NaN === NaN);// false
console.log(NaN == NaN);// false
2.9.1.3.合并
const STU1 = {
name : '王小二',
age : 18,
birth : '2001-01-01',
info1: '一个好学生'
};
const STU2 = {
name : '李小三',
age : 22,
sex : '女',
info2: '也是一个好学生'
}
Object.assign(STU1, STU2) // 将STU1和STU2合并到 STU1
console.log( STU1 );
// 结果是合并结果
// {
// age : 22,
// birth : "2001-01-01",
// info1 : "一个好学生",
// info2 : "也是一个好学生",
// name : "李小三",
// sex : "女"
// }
console.log( STU2 ); // 不变化
2.9.1.4.拷贝
// 1、拷贝对象
let s1 = { name: "王小二", age: 15 }
let s2 = { ...s1 }
console.log( s2 ) //{ name:"王小二", age:15 }
// 2、合并对象
let age1 = { age: 15 }
let name1 = { name: "王小二" }
let s3 = { name : "李小三" }
s3 = { ...age1, ...name1 }
console.log( s3 ) // {age: 15, name: '王小二'}
2.9.1.5.( ES 9 )Object.fromEntries
从 二维数组 / Map 创建对象
//二维数组
const result1 = Object.fromEntries([
['name','王小二'],
['study', 'Java,html,js']
]);
console.log(result1) //{name: "王小二", study: "Java,html,js"}
//Map
const m = new Map();
m.set('name','李小三');
m.set('hobby', ['电影','美食','旅游'] )
const result2 = Object.fromEntries(m);
console.log(result2); //{name: "李小三", hobby: Array(3)}
也可以在创建时 指定这些属性
const obj = Object.create(null, {
name: {
//设置值
value: '李小三',
//属性特性
writable: true,
configurable: true,
enumerable: true
}
});
console.log(obj)
2.9.2.简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
let name = '王小二';
let sayHello = function(){
console.log('大家好!!');
}
// const STU = {
// name : name,
// sayHello : sayHello,
// study: function(){
// console.log("我们一起学 js");
// }
// }
const STU = {
name,
sayHello,
study(){
console.log("我们一起学 js");
}
}
console.log(STU);
STU.sayHello()
几种对象函数的写法:
let person3 = {
name: "王小二",
// 以前:
eat: function (food) {
console.log(this.name + "在吃" + food);
},
//箭头函数this不能使用,对象.属性
eat2: food => console.log(person3.name + "在吃" + food),
// 匿名
eat3(food) {
console.log(this.name + "在吃" + food);
}
}
person3.eat("香蕉");
person3.eat2("苹果")
person3.eat3("橘子");
2.9.3.( ES 9 )Rest/Spread 属性
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
//rest 参数
function connect({host, port, ...user}){
console.log(host); // 127.0.0.1
console.log(port); // 3306
console.log(user); // { username: 'root', password: 'root', type: 'master' }
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
//对象合并
const teamOne = {
a : '王小二',
b : '李小三'
}
const teamTwo = {
c : '赵小四',
d : '张不开',
e : '刘小六'
}
const team = {
...teamOne,
...teamTwo
}
console.log(team) //{a: '王小二', b: '李小三', c: '赵小四', d: '张不开', e: '刘小六'}
2.10. 扩展Map
ES6 提供了 Map 数据结构。
它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
Map会按照插入的顺序来迭代元素,而对象中的键值对没有固定的顺序。
Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。
2.10.1.创建和初始化
// 创建一个空 Map
let map1 = new Map();
// 使用数组形式初始化 Map
let map2 = new Map([
['name', '王小二'],
[123, 'abc'],
[{ key: 'objectKey' }, 'Value for object key']
]);
console.log(map2);
// 使用可迭代对象(如另一个 Map 或 Set)初始化
let obj = { a: 1, b: 2 };
let entries = Object.entries(obj);
let map3 = new Map(entries);
console.log(map3); // Map(2) { 'a' => 1, 'b' => 2 }
2.10.2.Map 的属性和方法
-
size 返回 Map 的元素个数
-
set 增加一个新元素,返回当前 Map
-
get 返回键名对象的键值对数组
-
has 检测 Map 中是否包含某个元素,返回 boolean 值
-
clear 清空集合,返回 undefined
//声明 Map
let m = new Map();
//添加元素
m.set('name','王小二');
m.set('sayHello', function(){
console.log("大家好!!");
});
let key = {
study : 'JAVA'
};
m.set(key, ['spring','mybatis','springmvc']);
//size
console.log(m.size);
//删除
m.delete('name');
//获取
console.log(m.get('name'));
console.log(m.get('sayHello'));
console.log(m.get(key));
//清空
// m.clear();
//遍历
for(let v of m){
console.log(v);
}
console.log(m);
2.11.函数优化
2.11.1.箭头函数
ES6 允许使用「箭头」(=>)定义函数。
let fn1 = function(){
console.log('function')
}
fn1()
let fn2 = ()=>{
console.log('=>')
};
fn2()
2.11.1.1.写法
// 声明一个函数
let fn = (a,b) => {
return a + b;
}
// 调用函数
let result = fn(1, 2);
console.log(result);
// 如果形参只有一个,则小括号可以省略
let fn3 = num => {
return num * 10;
};
// 函数体如果只有一条语句,则花括号可以省略
let fn4 = ()=>console.log('hello')
// 函数的返回值为该条语句的执行结果
let fn5 = score => score * 20;
let result = fn5(10);
console.log(result)
// 当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来
let f = (id,name) => ({id:id,name:name});
console.log( f(1,'王小二') ) // {id: 1, name: '张三'}
箭头函数+解构
const person = {
name: "王小二",
age: 21,
language: ['java', 'js', 'css']
}
function hello(person){
console.log("hello," + person.name)
}
//箭头函数+解构
var hello2 = ({name}) => console.log("hello," + name);
hello2(person);
2.11.1.2.this ***
this 指向声明时所在作用域中 this的值
// 设置 window 对象的 name 属性
window.name = '王小二';
let name = '赵静子';
console.log( this )
function getName(){
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
//直接调用
getName(); // 王小二
getName2(); // 王小二
注意:this 是静态的 , 箭头函数不会更改 this 指向,用来指定回调函数会非常合适
箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
const STU = {
name: "李小三"
}
//call 方法调用
getName.call(STU); // 李小三
getName2.call(STU); // 王小二
2.11.1.3.不能作为构造函数
箭头函数不能作为构造函数实例化
let Sss = function (name, age) {
this.name = name;
this.age = age;
}
let wang = new Sss('王小二',12);
console.log(wang);
let Stu = (name, age) => {
this.name = name;
this.age = age;
}
let li = new Stu('李小三',13); //Uncaught TypeError: Stu is not a constructor
console.log(li);
2.11.1.4.不能使用 arguments
let fn6 = function () {
console.log(arguments);
}
fn6(1,2,3);
let fn7 = () => {
console.log(arguments);
}
fn7(1,2,3); //Uncaught ReferenceError: arguments is not defined
2.11.2. rest 参数(不定参数)
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
// ES5 获取实参的方式
// function getName1(){
// console.log(arguments);
// }
// getName1('王小二','李小三','赵小四');
// rest 参数
// function getName2(...args){
// console.log(args);// filter some every map
// }
// getName2('王小二','李小三','赵小四');
// getName2('王小二','李小三');
// rest 参数必须要放到参数最后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
console.log(args.length);
}
fn(1,2,3,4,5,6);
注意:rest 参数非常适合不定个数参数函数的场景
2.11.3. spread 扩展运算符
扩展运算符(spread)也是三个点(…)。
它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
// 声明一个数组
const names = ['王小二','李小三','赵小四'];
// 声明一个函数
function getName(){
console.log(arguments);
}
getName(...names); // getName('王小二','李小三','赵小四')
2.11.4.参数设置默认值
//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
// 判断b是否为空,为空就给默认值1
b = b || 1;
return a + b;
}
// 传一个参数
console.log(add(10));
//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
return a + b;
}
console.log(add2(20));
2.11.5.( ES 11 )可选链操作符
使用参数之前 先判断参数有效性, 否则使用未传入的参数会报错
使用 ?.
运算符, 可以自动根据参数有效性进行判断, 如果参数无效, 不报错, 返回 undefined
// ?.
function main(config){
// const dbHost = config && config.db && config.db.host;
const dbHost = config?.db?.host;
console.log(dbHost);
}
// main({
// db: {
// host:'192.168.1.100'
// }
// })
main();