Es6个人使用心得
变量声明
let 和const
- let 允许创建块级作用域,ES6 推荐在函数中使用 let 定义变量,而非 var:
- 同样在块级作用域有效的另一个变量声明方式是 const,它可以声明一个常量。ES6 中,const 声明的常量类似于指针,它指向某个引用,也就是说这个「常量」并非一成不变的
- 需要注意的地方
3.1. 当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
3.2. const 在声明时必须被赋值
箭头函数
引入箭头函数有两个方面的作用:更简短的函数并且不绑定this。
- 更简短的函数
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
elements.map(function(element) {
return element.length;
}); // 返回数组:[8, 6, 7, 9]
// 上面的普通函数可以改写成如下的箭头函数
elements.map((element) => {
return element.length;
}); // [8, 6, 7, 9]
// 当箭头函数只有一个参数时,可以省略参数的圆括号
elements.map(element => {
return element.length;
}); // [8, 6, 7, 9]
// 当箭头函数的函数体只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号
elements.map(element => element.length); // [8, 6, 7, 9]
// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,而 `lengthFooBArX` 则只是个变量名,
// 可以替换成任意合法的变量名
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
- 不绑定this
2.1. 在箭头函数出现之前,每个新定义的函数都有它自己的 this值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被作为“对象方法”调用则为基础对象等)。This被证明是令人厌烦的面向对象风格的编程。
2.2. 在全局环境下,this 始终指向全局对象(window), 无论是否严格模式;
2.3. 对象中的this,对象内部方法的this指向调用这些方法的对象,函数的定义位置不影响其this指向,this指向只和调用函数的对象有关。多层嵌套的对象,内部方法的this指向离被调用函数最近的对象(window也是对象,其内部对象调用方法的this指向内部对象, 而非window)。
2.4.箭头函数中的 this,由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值,所以 call() / apply() / bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响。考虑到 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。(可以忽略是否在严格模式下的影响)
因为箭头函数可以捕获其所在上下文的this值
模板字符串(template string)
在ES6之前,我们往往这么处理模板字符串:
通过“\”和“+”来构建模板
而对ES6来说
基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;
ES6反引号(``)直接搞定;
$("body").html(`This demonstrates the output of HTML content to the page,
including student's ${name}, ${seatNumber}, ${sex} and so on.`);
解构赋值
// 对象
const student = {
name: 'James',
age: 24,
sex: '男'
}
// 数组
// const student = ['James', 24, '男'];
// ES5;
const name = student.name;
const age = student.age;
const sex = student.sex;
console.log(name + ' --- ' + age + ' --- ' + sex);
// ES6
const { name, age, sex } = student;
console.log(name + ' --- ' + age + ' --- ' + sex);
函数的参数默认值
在ES6之前,我们往往这样定义参数的默认值:
// 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
Spread / Rest 操作符
Spread / Rest 操作符指的是 …,具体是 Spread 还是 Rest 需要看上下文语境。
当被用于迭代器中时,它是一个 Spread 操作符:
function foo(x,y,z) {
console.log(x,y,z);
}
let arr = [1,2,3];
foo(...arr); // 1 2 3
当被用于函数传参时,是一个 Rest 操作符:当被用于函数传参时,是一个 Rest 操作符:
function foo(...args) {
console.log(args);
}
foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]
for…of 和 for…in
for…of 用于遍历一个迭代器,如数组:
let letter = ['a', 'b', 'c'];
letter.size = 3;
for (let letter of letters) {
console.log(letter);
}
// 结果: a, b, c
for…of 也可用于遍历一个对象,
let letter = {name: 'james', age: '21'}
for (let letter of letters) {
console.log(letter);
}
// 结果:name age
for…in 用来遍历对象中的属性:
let stu = ['Sam', '22', '男'];
stu.size = 3;
for (let stu in stus) {
console.log(stu);
}
// 结果: Sam, 22, 男
模块化 export 和 import
import 导入模块、export 导出模块
可以直接在任何变量或者函数前面加上一个 export 关键字,就可以将它导出。
在一个文件中:
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
Promise
在promise之前代码过多的回调或者嵌套,可读性差、耦合度高、扩展性低。通过Promise机制,扁平化的代码机构,大大提高了代码可读性;用同步编程的方式来编写异步代码,保存线性的代码逻辑,极大的降低了代码耦合性而提高了程序的可扩展性。
就是用同步的方式去写异步代码。
//Promise对象 ---> 用来传递异步操作过来的数据的
//Pending(等待、处理中) ---> Resolve(完成,fullFilled) ---> Reject(拒绝,失败)
//这里只是定义,还没开始执行
var p1 = new Promise(function(resolve,reject){
resolve(1); // 成功了,返回一个promise对象1
// reject(2); // 失败了
});
// 接收成功和失败的数据,通过then来传递
// then也是返回一个promise对象,会继续往下传递数据,传递给下一个then
p1.then(function(value){
// resolve
console.log(value); //执行打印1
return value + 1; // 1
alert(`成功了:${value}`);
},function(value){
// reject
alert(`失败了:${value}`);
}).then(function(value){
console.log(value); // 2
});
//catch捕获异常错误
var p1 = new Promise(function(resolve,reject){
resolve('成功了'); //返回一个promise对象“成功了”
});
//then也是返回一个promise对象,会继续往下传递数据
p1.then(function(value){
console.log(value); //打印“成功了”
// throw是用来抛错误的
throw '发生了点小意外';
}).catch(function(e){
// catch用来捕获这个错误的 ---> 追踪
console.log(e);
});
//all ---> 全部,用于将多个promise对象,组合,包装成
//Promise.all([p1,p2,p3,...]); 所有的promise对象,都正确,才走成功
//否则,只要有一个错误,就走失败
var p1 = Promise.resolve(1);
var p2 = Promise.reject(0);
Promise.all([true,p1,p2]).then(function(obj){
console.log(`成功了:${obj}`);
},function(obj){
console.log(`失败了:${obj}`);
});
// race ---> 返回的也是一个promise对象
//最先执行的的promise结果,哪个最快我用哪个,所以下面打印的是one
var p1 = new Promise(function(resolve,reject){
setTimeout(resolve,50,'one');
});
var p2 = new Promise(function(resolve,reject){
setTimeout(resolve,100,'two');
});
Promise.race([p1,p2]).then(function(val){
console.log(val);
});
//resolve ---> 生成一个成功的promise对象
//语法规则:Promise.resolve(val); // 普通值
// Promise.resolve(arr); // 数组之类
//Promise.resolve(promise); // 传递另一个promise对象
//传递普通值
Promise.resolve('success').then(function(val){
// 注意resolve,走得是这里
console.log(val); // success
},function(err){
console.log("err:"+ err);
});
//传递数组
Promise.resolve([1,2,3]).then(function(val){
// 注意resolve,走得是这里
console.log(val); // [1,2,3]
},function(err){
console.log(err);
});
//传递一个promise对象
var p1 = Promise.resolve(520);
var p2 = Promise.resolve(p1);
p2.then(function(val){
//从p1那边传递过来的
console.log(val); // 520
});