ES6语法
之前要是没有了解过ES6语法的,建议看看阮一峰老师写的ES6
1 let 和 const
var let const 三者区别
-
1.变量提升
- var存在变量提升,在函数的最顶部
- let和const声明不会提升
-
2.作用域
- let和const是块级作用域
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
-
3.重复声明
- var 可以重复定义
- let和const不可以重复定义,否则报错
- 4.const常量不可修改
- const声明一个只读的常量。一旦声明,常量的值就不能改变
变量的解构赋值
2.结构赋值
1. 数组的结构赋值
// 以前
let a = 1;
let b = 2;
let c = 3;
// ES6
let [a, b, c] = [1, 2, 3];
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 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 [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
2. 对象的结构赋值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
对象的解构也可以指定默认值
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var {x: y = 3} = {};
y // 3
var {x: y = 3} = {x: 5};
y // 5
3. 字符串的解构赋值
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
let {length : len} = 'hello';
len // 5
4. 函数参数的解构赋值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
模板字符串
基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;
ES6反引号()直接搞定;
// bad
const foo = 'this is a' + example;
// good
const foo = `this is a ${example}`;
字符串新增方法
includes() 、startsWith()、endsWith()
JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法
- includes():返回布尔值,表示是否找到了参数字符串
- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部
- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
这三个方法都支持第二个参数,表示开始搜索的位置
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
repeat()
repeat方法返回一个新字符串,表示将原字符串重复n次
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
参数如果是小数,会被取整
'na'.repeat(2.9) // "nana"
padStart()、padEnd()
字符串补全长度的功能,如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全
也可以在时间格式化中,判断数是否小于10,去补0
'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"
数组的拓展
ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变
// ES5的写法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45
// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
Number.isInteger()
Number.isInteger()用来判断一个数值是否为整数
Number.isInteger(25) // true
Number.isInteger(25.1) // false
Math.trunc()
Math.trunc方法用于去除一个数的小数部分,返回整数部分
Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0
对于非数值,Math.trunc内部使用Number方法将其先转为数值
Math.trunc('123.456') // 123
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0
对于空值和无法截取整数的值,返回NaN
Math.trunc(NaN); // NaN
Math.trunc('foo'); // NaN
Math.trunc(); // NaN
Math.trunc(undefined) // NaN
Math.sign()
Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值
它会返回五种值
- 参数为正数,返回+1
- 参数为负数,返回-1
- 参数为 0,返回0
- 参数为-0,返回-0
- 其他值,返回NaN
函数的扩展
1. 函数参数的默认值
// ES6之前,当未传入参数时,text = 'default';
function printText(text) {
text = text || 'default';
console.log(text);
}
// ES6;
function printText(text = 'default') {
console.log(text);
}
printText('hello'); // hello
printText();// default
name 属性
函数的name属性,返回该函数的函数名
function foo() {}
foo.name // "foo"
箭头函数
ES6 允许使用“箭头”(=>)定义函数
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
箭头函数有几个使用注意点
- 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
- 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数
数组的拓展
扩展运算符
扩展运算符(spread)是三个点(…),将一个数组转为用逗号分隔的参数序列
该运算符主要用于函数调用
function add(x, y) {
return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
扩展运算符的应用
复制数组
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
与解构赋值结合
扩展运算符可以与解构赋值结合起来,用于生成数组
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
字符串
扩展运算符还可以将字符串转为真正的数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]
Array.from()
Array.from方法用于将两类对象转为真正的数组
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()方法用于将一组值,转换为数组
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
数组实例的 fill()
fill方法使用给定值,填充一个数组
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
数组的find() 方法
find() 方法返回通过测试函数的第一个数组元素的值
var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
数组的 findIndex() 方法
findIndex() 方法返回通过测试函数的第一个数组元素的索引
var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
数组实例的 includes()
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
对象的扩展
属性的简洁表示法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
// 等同于
const baz = {foo: foo};
解构赋值
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
扩展运算符
对象的扩展运算符(…)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
Object.assign()
Object.assign方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}