###解构赋值用途 1 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
交换 x y的值。 2 从函数返回多个值 函数只能返回一个值,若要返回多个值,将其放在数组或对象中返回,通过解构赋值,将其取出
// 返回一个数组
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
3 函数参数的定义 解构赋值方便将一组参数与变量名对应
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
4 遍历map结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
方便获取键名和键值
字符串扩展
1 字符串遍历器
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
2 模板字符串 传统写法:
$('#result').append(
'There are <b>' + basket.count + '</b> ' +
'items in your basket, ' +
'<em>' + basket.onSale +
'</em> are on sale!'
);
es6模板字符串 变量名${}引入
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
模板字符串可以调用函数
function fn() {
return "Hello World";
}
`foo ${fn()} bar`
// foo Hello World bar
模板字符串嵌套
const tmpl = addrs => `
<table>
${addrs.map(addr => `
<tr><td>${addr.first}</td></tr>
<tr><td>${addr.last}</td></tr>
`).join('')}
</table>
`;
const data = [
{ first: '<Jane>', last: 'Bond' },
{ first: 'Lars', last: '<Croft>' },
];
console.log(tmpl(data));
// <table>
//
// <tr><td><Jane></td></tr>
// <tr><td>Bond</td></tr>
//
// <tr><td>Lars</td></tr>
// <tr><td><Croft></td></tr>
//
// </table>
###函数的扩展 rest函数
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
上面代码的add函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数。
箭头函数可以与变量结构结合使用。
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
#####箭头函数 注意点: 箭头函数没有自己的this 不可以当构造函数,不可以对new一个箭头函数。 this 指向
function foo() {
return () => {
return () => {
return () => {
console.log('id:', this.id);
};
};
};
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1
this的指向只有一个 函数foo的this,内部箭头函数没有自己 this ,继承外层foo函数的this。 由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。
递归
function digui (n) {
if(n===1) return 1;
return n*digui(n-1)
}
digui(5) //120
计算n的阶乘 复杂的O(n)
尾递归 :尾调用自身 称为 尾递归
function factorial(n, total) {
if (n === 1) return total;
return factorial(n - 1, n * total);
}
factorial(5, 1) // 120
如果改写成尾递归,只保留一个调用记录,复杂度 O(1) 。
###数组的扩展 ... 扩展运算符替代apply函数
// ES5 的写法
function f(x, y, z) {
// ...
}
var args = [0, 1, 2];
f.apply(null, args);
// ES6的写法
function f(x, y, z) {
// ...
}
let args = [0, 1, 2];
f(...args);
apply函数 可以展开数组 用扩展符更加方便
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
####扩展运算符的引用 1 . 复制数组 数组是符合的数字类型 直接赋值只是复制了指向底层数据结构的指针 ,并非克隆一个全新数组
const a1 = [1, 2];
const a2 = a1;
a2[0] = 2;
a1 // [2, 2]
a2并非a1的克隆 二十只想同一份数据的指针 修改a2会导致a1改变 ES5复制数组
const a1=[1,2];
const a2=a1.concat();
a2[0] = 2;
a1 // [1, 2]
扩展运算符复制数组
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
2 . 合并数组
const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];
const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];
a3[0] === a1[0] // true
a4[0] === a1[0] // true
上代码中 a3,a4是通过不用方法合并的新数组,但是他们的成员是对原数组成员的引用 是浅拷贝 ,修改引用指向的值 新的数组也会改变 3 . 与解构赋值结合 生成数组
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
扩展运算符用于数组赋值只能放在数组第一位 否则会报错 例子
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错
const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 报错
4 . 字符串 将字符串转为数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]