haohao

ES6入门: 需要掌握的基本语法

cover

ES6是什么

1. ES (ECMAScript) 和JavaScript的关系

ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。日常场合,这两个词是可以互换的。

2. ES6和ECMAScript 2015的关系

ES6,一般是指ECMAScript 2015标准,但有时也表示一种泛指,是指JavaScript语言的下一代标准。涵盖了ECMAScript 2015,2016,2017等版本,而ECMAScript 2015则是正式名称,特指该年发布的正式版本的语言标准。

Babel转码器

Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。去官网选择自己习惯的工具来使用使用Babel吧!

let和const命令

let和const与var类似都是用来声明变量的,但又有各自不同的用途。let与var对比,看代码:

1
2
3
4
5
6
7
8
var name = 'haohao';
if(true){
var name = 'jack';
console.log(name) //jack
}
console.log(name) //jack

ES5只有全局作用域和块级作用域,导致内层变量覆盖外层变量,使得两次输出的都是jack。而let为JS新增了块级作用域,因此它声明的变量只在let命令所在的代码块有效,具体看代码:

1
2
3
4
5
6
7
8
let name = 'haohao';
if(true){
let name = 'jack';
console.log(name) //jack
}
console.log(name) //haohao

const用来声明常量,一旦声明就不能改变。当我们尝试改变const声明的常量时,浏览器就会报错。

1
2
3
const PI = Math.PI
PI = 23 //Module build failed: SyntaxError: /es6/app.js: "PI" is read-only

引用其他Module中声明的变量,用const来声明可以避免对其重命名而导致出现BUG。

1
const {width, height} = window.get('Dimension');

解构 (Destructuring)

解构 (Destructuring) 是指按照某种模式,从对象或数组中提取值对指定的变量进行赋值。

ES6之前为变量赋值:

1
2
3
let name = 'jack';
let addr = 'cn';
let sex = 'male';

ES6可以这样:

1
2
3
4
5
let [name,addr,sex] = ['jack','cn','male'];
name //jack
addr //cn
sex //male

默认值:

1
2
3
4
5
let [name,addr,sex = 'male'] = ['jack','cn'];
name //jack
addr //cn
sex //male

关于对象以前这样:

1
2
3
4
5
6
7
let name = 'jack';
let addr = 'cn';
let sex = 'male';
let student = { name:name, addr:addr, sex:sex }
console.log(student);
//Object { name:'jack', addr:'cn', sex:'male' }

ES6可以这样:

1
2
3
4
5
6
7
let name = 'jack';
let addr = 'cn';
let sex = 'male';
let student = { name, addr, sex }
console.log(student);
//Object { name:'jack', addr:'cn', sex:'male' }

还有这样:

1
2
3
4
5
6
let student = { name:'kene', addr:'us', sex:'male' }
let { name, sex } = student;
let { addr } = student;
console.log(name, addr, sex);
//kene us male

模板字符串 (template string)

传统模板字符串:

1
2
3
4
5
$('#showId').append(
"Hello,everyone!" +
"I am Jack."+
"I like eat " + fruits + "!"
);

ES6模板字符串:

1
2
3
4
5
$('#showId').append(`
Hello,everyone!
I am Jack.
I like eat ${fruits}!
`);

反引号标识起始,${}引入变量,所有的空格缩进保存输出。

箭头函数 (arrow functions)

ES6允许使用“箭头”(=>)定义函数。

1
2
var func = i => i + 1;
var func = (a, b) => {a++; b++; return a + b;}

上面的箭头函数等同于:

1
2
3
4
5
6
7
8
9
var func = function(i) {
return i + 1;
};
var func = function(a, b) {
a++;
b++;
return a + b;
}

当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。有一种使用场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
constructor(){
this.name = 'person';
}
sayHello(){
setTimeout(function(){
console.log(this.name + 'says hello.');
});
}
}
let p = new Person();
p.sayHello();
//undefined says hello.

运行上面的代码会报错,这是因为setTimeout中的this指向的是全局对象。有了箭头函数上述问题便可迎刃而解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
constructor(){
this.name = 'person';
}
sayHello(){
setTimeout(() => {
console.log(this.name + 'says hello.');
});
}
}
let p = new Person();
p.sayHello();
//person says hello.

类 (Class)

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念。新的class写法让对象原型的写法更加清晰、更像面向对象编程的语法,也更加通俗易懂。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
constructor(){
this.name = 'person';
}
sayHello(){
setTimeout(() => {
console.log(this.name + 'says hello.');
});
}
}
let p = new Person();
p.sayHello();
//person says hello.

上面代码首先用class定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。简单地说,constructor内定义的方法和属性是实例对象自己的,而constructor外定义的方法和属性则是所有实例对象可以共享的。

ES6的继承机制,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。

1
2
3
4
5
6
7
8
9
10
11
class Student extends Person {
constructor(){
super();
this.name = 'student';
}
}
let s = new Student();
s.sayHello();
//student says hello.

上面定义了一个Student类,该类通过extends关键字,继承了Person类的所有属性和方法。

子类Student必须在constructor方法中调用super方法,否则新建实例时会报错,子类就得不到this对象。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。

export和import

ES6的模块化功能。
以前这样写:

1
2
3
4
5
6
7
8
//content.js
module.exports = 'apple';
//index.js
var fruits = require('./content.js');
console.log(fruits);
//apple

ES6这样:

1
2
3
4
5
6
7
8
//content.js
export default 'apple';
//index.js
import fruits from './content.js';
console.log(fruits);
//apple

深入点,看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//content.js
export const KIND = 'Thailand Apple';
export default 'apple';
export function say(){
return 'I like apple!';
}
//index.js
import fruits, { say, KIND } from './content.js';
//如果只导入say //import { say } from './content.js';
console.log(fruits);
console.log(KIND);
say();
//apple
//Thailand Apple
//I like apple!

修改变量名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//content.js
export const KIND = 'Thailand Apple';
export default 'apple';
export function say(){
return 'I like apple!';
}
//index.js
import fruits, { say, KIND as type } from './content.js';
console.log(fruits);
console.log(type);
say();
//apple
//Thailand Apple
//I like apple!

整体加载,*为指定的一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//content.js
export const KIND = 'Thailand Apple';
export default 'apple';
export function say(){
return 'I like apple!';
}
//index.js
import fruits, * as content from './content.js';
console.log(fruits);
console.log(content.type);
content.say();
//apple
//Thailand Apple
//I like apple!


联系我

Wechat ID

公众号

生活不止于眼前的苟且, 还有诗和远方的田野