1.ES6介绍
ES6是 JavaScript 语⾔的下⼀代标准,在 2015 年 6 ⽉正式发布。它的⽬标,是使得 JavaScript 语⾔可以⽤来编写复杂的⼤型应⽤程序,成为企业级开发语⾔。之前我们学的是 ES5,是在2011年发布的。ES6 既是⼀个历史名词,也是⼀个泛指,含义是 5.1 版以后的 JavaScript 的下⼀代标准,涵盖了 ES2015、ES2016、ES2017 等等,⽽ ES2015 则是正式 名称,特指该年发布的正式版本的语⾔标准。 nodejs对ES6的⽀持很⾼,⽬前多数浏览器也对ES6进⾏了⽀持,不过我们在企业级开发中 仍需要通过Babel将ES6的⾼级语法转换为ES5,这样使得我们的程序兼容性更强。
2.变量声明
2.1 let
let与var类似,但是不像var那么奇葩,通过let声明的变量具有如下特点:
- 具有局部作⽤域
- 不存在变量声明的提升
- 不可以对⼀个变量进⾏重复声明
- 暂时性死区:在⼀个代码块中,let可以锁定某个变量
let a = 3;
2.2 const
const⽤于声明⼀个常量,⼀旦声明,常量的值就不能改变。此外,const具有let的所有特点。
const b = 3;
b++; //error
但却可以引用类型值的属性名和属性值,还可以添加属性
const obj = {age:1}
obj.age++; // age 2
3.解构赋值
ES6 允许按照⼀定模式,从数组和对象中提取值,对变量进⾏赋值,这被称为解构。解构 的本质是模式匹配,也就是说只要等号两边的模式相同,左边的变量就会被赋予对应的值。解构 时如果解构不成功,变量的值就等于 undefined 。
3.1对象结构
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
let {foo} = {bar: 'baz'}; //foo为 undefined
let {name,age,gender} = {name:"terry",age:12} // gender 为 undefinde
let {foo,bar = '2'} = { foo:'1'} //可以为属性赋默认值,默认值值可以被所传入的值覆盖,如没有传值,结果就为默认值
let {push} = [1,2,3] // 获得数组原型上的push方法
3.2数组结构
通过中括号来匹配等号右边的数组值。对于 Set 结构,也可以使⽤数组的解构赋值。
let [a,b,c] = ['terry','tom','jacky']
let [a,b,c,d] = ['terry','tom','jacky'] // d 为 undefined
let [a,b,c,d='vicky'] = ['terry','tom','jacky'] // d = 'vicky'
let [foo, [[bar], baz]] = [1, [[2], 3]];
let [head, ...tail] = [1, 2, 3, 4]; // head = 1 tail = [2,3,4]
let [x, y, ...z] = ['a']; // x = 'a', y 为 undefined , z 为 [ ]
let [a, [b], d] = [1, [2, 3], 4]; // 不完全解构
let [x, y, z] = new Set(['a', 'b', 'c']); //解构set集
let [x, y = 'b'] = ['a', undefined]; // 默认值 x='a', y='b
4.字符串拓展
4.1 遍历
ES6 为字符串添加了遍历器接⼝,使得字符串可以被 for...of 循环遍历。
let str = "hello world"
for(let s of str){ console.log(s); }
4.2 实例方法(声明在原型对象中) ( 静态方法(声明在构造函数))
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
repeat()
'hello'.repeat(2) // "hellohello"
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
trimStart()
trimEnd()
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
'aabbcc'.replace('b', '_') // 'aa_bcc' // 常用
'aabbcc'.replace(/b/g, '_') // 'aa__cc' // 常用
'aabbcc'.replaceAll('b', '_') // 'aa__cc'
5.数值拓展
Number.isFinite(), Number.isNaN()
与isFinite、isNaN不同,这两个新⽅法只对数值有效, Number.isFinite() 对于⾮数值⼀律返回 false , Number.isNaN() 只有对于 NaN 才返回 true ,⾮ NaN ⼀律返回 false 。
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.parseInt(), Number.parseFloat()
Number.parseInt('12.34') // 12 遇到非数字的就停止转换,不保留小数
Number.parseFloat('123.45#') // 123.45 跟上相同,保留小数
Number.isInteger()
Number.isInteger() ⽤来判断⼀个数值是否为整数
Number.isInteger(25) // true
Number.isInteger(25.1) // false
6.对象拓展
6.1 对象简写
let name = "terry"
let age = 12;
let sayHello = function(){ console.log('hello world'); }
let obj = { name,age,sayName,foo(){ } }
6.2 对象的扩展运算符
对象中也可以使⽤扩展运算符
解构赋值
let {name,...other} = { name: 'terry', age: 12, gender: 'male' };
name // 'terry'
other // {age: 12, gender: 'male'}
扩展运算符
let obj = {name: 'terry', age: 12, gender: 'male'}
let o = {...obj}
o // {name: 'terry', age: 12, gender: 'male'}
6.3Object静态⽅法扩展
Object.is()
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign() 重要方法
⽤于对象的合并,将源对象(source)的所有可枚举属性,复制到⽬标对象(target)
let obj1 = { name: 'terry', age: 13, gender: 'male' }
let obj2 = Object.assign({},obj1) // 深拷贝
obj1 === obj2 // false
obj1.age = obj.age + 1;
obj1.age // 14
obj2.age // 13
如果源对象中的对象存在嵌套关系,进⾏浅拷⻉
let o1 = {a:{age:1}}
let o2 = Object.assign({},o1) // 外层为深拷贝,内层的引用数据类型则为浅拷贝
o1 === o2 // false
o1.a.age = 2
o2.a.age // 2
Object.setPrototypeOf()
为某个对象设置原型
let prototype = {
foo(){console.log('foo')},
bar(){console.log('bar')}
}
let obj = {}
Object.setPrototypeOf(obj,prototype)
obj:要设置原型对象的对象。
prototype:该对象的新原型对象或null,否则抛出TypeError异常。
返回值: 设置了新的原型对象的对象
Object.getPrototypeOf()
获取某个对象的原型
Object.getPrototype(obj)
7. 数组拓展
7.1 扩展运算符
可以看做是rest的逆运算,⽤于将数组中的元素拆分出来
console.log(...[1, 2, 3]) // 1,2,3
7.2. 静态⽅法扩展
let arrayLike = {
'0': 'a',
1': 'b',
'2': 'c',
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
Array.of()
⽤于将⼀组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]
// 模拟实现
function ArrayOf(){
return [ ].slice.call(arguments);
}
7.3. 实例⽅法拓展
find() 和 findIndex()
与fifilter类似,属于数组类型⽅法, find ⽅法⽤于找出第⼀个符合条件的数组成员。它的参数是⼀个回调函数,所有数组成员依次执⾏该回调函数,直到找出第⼀个返回值为 true 的 成员,然后返回该成员。如果没有符合条件的成员,则返回 undefined 。 findIndex ⽅法的⽤法与 find ⽅法⾮常类似,返回第⼀个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回 -1 。
[1, 4, -5, 10].find((n) => n < 0) //-5
[1, 5, 10, 15].findIndex(value => value>9) //2
fill()
使⽤给定值,填充⼀个数组。
new Array(3).fill(7) // [7, 7, 7]
includes()
返回⼀个布尔值,表示某个数组是否包含给定的值,与字符串的 includes ⽅法类似。
['jacky','tom','vicky'].includes('tom') //true
flat() // 重要
该⽅法⽤于将嵌套的数组“拉平”,变成⼀维的数组。该⽅法返回⼀个新数组,对原数据没 有影响。 flat() 默认只会“拉平”⼀层,如果想要“拉平”多层的嵌套数组,可以将 flat() ⽅ 法的参数写成⼀个整数,表示想要拉平的层数,默认为1。 如果不管有多少层嵌套,都要转成⼀ 维数组,可以⽤ Infinity 关键字作为参数。
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity) // [1, 2, 3]
flatMap()
该⽅法对原数组的每个成员执⾏⼀个函数(相当于执⾏ Array.prototype.map() ),然后 对返回值组成的数组执⾏ flat() ⽅法。该⽅法返回⼀个新数组,不改变原数组。 该⽅法只能 展开⼀层数组。
// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2,3,4].flatMap((x) => [x ,x * 2]) // [2,4,3,6,4,8]
8. 函数拓展王
8.1. 函数默认值
声明参数的时候,可以通过'='为参数设置⼀个默认值
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
8.2. 参数解构
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
8.3. rest参数
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
8.4. 箭头函数
更简便的函数写法。如果箭头函数不需要参数或需要多个参数,就使⽤⼀个圆括号代表参数 部分;如果箭头函数的代码块部分多于⼀条语句,就要使⽤⼤括号将它们括起来,并且使⽤ return 语句返回。 箭头函数中的this指向包含该箭头函数的外部函数的this
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
var sum = (num1, num2) => { return num1 + num2; }