ES6
这里我们介绍一些常用的ES6的内容。也是我们日常工作中使用最多的。
变量定义
拒绝使用 var
来定义。采用 let
和 const
。
因为不同于 var
的函数作用域,const
和 let
都是块级作用域。
不再使用 var
, 会给我们的代码带来很多好处,比如以前常见的变量提升问题也就不存在了。
示例:
let count = 1;
count += 1;
这里列举一个常在面试中出现的题目:
for(var i = 0; i < 10; i++) {
setTimeout(function() {console.log(i)}, 0);
}
请问这段代码输出什么?
执行完这段代码,发现输出 10 个 10
如何修改才能让这段代码输出 0 ~ 9?
我们只需要将 var
修改为 let
就要吧实现输出 0 ~ 9 了。
使用原则:定义不可变的变量,使用
const
,定义一个会被修改的变量使用let
。
字符串模板
在ES6中,定义使用一对 ` 符号(英文输入法,数字1左边的键) 包裹起来的内容就是一个字符串模板,可以优雅的拼接一个带有变量的字符串。
示例:
const user = 'world';
console.log(`hello ${user}`); // hello world
// 多行
const bookname = 'Raect';
const content = `
Hello ${user},
Welcome to read ${bookname}.
`;
默认参数
我们在定义函数时,可以在形参中添加一个默认值。
示例:
function sayHello(user = 'world') {
console.log(`hello ${user}`);
}
sayHello() // hello world
同时也可以引申到定义一个字面量变量(见下文)时设定一个默认值。
示例:
function sayHello (props = {}) {
const {user = 'world'} = props;
console.log(`hello ${user}`);
}
sayHello() //hello world
箭头函数
js函数的另一种语法。不需要再用 function
关键字来声明,还可以省略 return
关键字。
更重要的是,可以继承当前上下文的 this
,这一点在React中经常用到。
示例:
使用 function
声明的函数:
function add (a, b) {
return a + b;
}
箭头函数:
(a, b) => (a + b)
当只有一个参数的时候,()
可以省略。例如:
[1, 2, 3].map(m => (m + 1)) // [2, 3, 4]
当箭头函数的函数体复杂的时候,需要使用 {}
将其包裹起来,并且需要使用 return
关键字。
示例:
[1, 2, 3].map((m, index) => {
return m + index;
});
// [1, 3, 5]
ES6的对象和数据
解构赋值
解构赋值可以直接从
Object
或者Array
中直接拿到数据作为变量。//对象 const user = {name: 'react', language: 'js'}; const {name, language} = user; console.log(name, language); // react js //数组 const list = [1, 2]; const [foo, baz] = list; console.log(foo, baz); // 1 2
函数参数也可以解构,例如:
const user = {name: 'react', language: 'js'}; const logUser = ({name, language}) => { console.log(name, language); }; logUser(user); // react js
函数参数在解构的时候还可以指定一个别名,让参数更有意义:
const logUser = ({payload: user}) => { console.log(user.name); } logUser({payload: {name: 'react'}}); // react
对象的字面量定义
对象解构的反向操作,例如:
const name = 'react', language = 'js'; const user = {name, language}; //等同于: const otherUser = {name: name, language: language};
另外在对象中定义函数的时候,可以省略
function
关键字。例如:const user = { name: 'react', getDetail() { //do something } } //等同于: const otherUser = { name: 'react', getDetail: function() { // do something } }
展开符 (...
)
ES6中只有对数组实现了这一功能,ES9对对象的展开功能也实现了,ES9之前需要加babel转化。
Spread Operator ...
获取数组或对象的项目。
例如:
// 数组:
const list1 = [1, 2, 3];
const list2 = [...list1, 4, 5];
console.log(list2);
//[1, 2, 3, 4, 5]
//对象
const obj1 = {name: 'react', language: 'js'};
const obj2 = {user: 'facebook', name: 'react', ...obj1};
console.log(obj2);
//{user: "facebook", name: "react", language: "js"}
展开符的操作中,执行的是从右向左的合并操作。也就是如果有对象的
key
相同,则会被右边的覆盖。
这一功能在React中经常使用,比如props
的扩展。
例如:
(props) => {
return <MyComponent {...props}/>
}
Promise
Promise是对之前我们通过函数回调处理异步方法的一种优雅实现方式。例如:
fetch('/api/users')
.then(res => res.json())
.then(data => data)
.catch(err => console.error(err));
定义一个Promise:
const delay = (timeout) => {
return new Promise((resolve, rejected) => {
if(timeout < 0) {
rejected();
} else {
setTimeout(resolve(), timeout);
}
});
};
delay(1000).then(() => {
console.log('executed');
});
Object.assgin()
Object.assgin()
也是我们编码中常用的。多个对象的合并,对象的深拷贝。
例如:
const obj1 = {name: 'react'};
const obj2 = Object.assgin({}, obj1, {language: 'js'});
当然,我们可以使用 ...
展开符来代替.
const obj1 = {name: 'react'};
const obj2 = {...obj1, language: 'js'});
for...of 循环
for...of
在循环中循环是迭代对象, for...of
允许你遍历 Arrays
(数组), Strings
(字符串), Maps
(映射), Sets
(集合)等可迭代的数据结构等。
示例:
const list = [1, 3, 4, 5, 6, 7];
for(let item of list) {
if(item % 2 === 0) {
break;
}
console.log(item);
}
//1
//3
class
ES6提出类的概念,作为对象的模板。通过 class
关键字,可以定义类。
基本上,ES6 的 class
可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
示例:
class Person {
name: '',
age: '',
constructor() {
}
}
类还可以继承,通过 extends
关键字。
class Student extends Person {
}
以上为我们开发中常见的ES6的内容,这些内容在React的开发中会经常用到。同时也建议我们尽量使用ES6语法来编写JS代码。