ES6–常用语法

1.let和const
ES6用两者来声明变量。
1.1.let
ES5使用var来声明变量
ES5只有全局作用域和函数作用域,没有块级作用域。如下代码所示:

// 示例1
var a = 'a';
if(true) {
	var a = 'b';
	console.log(a); // b
}
console.log(a);// b 
// 示例2
var a = [];
for (var i=0; i<10;i++) {
	a[i] = function() {
		console.log(i);
	}
}
a[6](); // 10

示例1:if内区块覆盖了外层变量。
示例2:函数作用域内的是全局变量

而ES6中的let实际上为js新增了块级作用域,它所声明的变量只在let所在代码块内有效。如下代码所示:

// 示例1
var a = 'a';
if(true) {
	let a = 'b';
	console.log(a); // b
}
console.log(a);// a
// 示例2
var a = [];
for (let i=0; i<10;i++) {
	a[i] = function() {
		console.log(i);
	}
}
a[6](); // 6

let声明的变量只在let所在快内有效
1.2.const
const用来声明常量。常量一旦被声明,就不能被改变,如下代码所示:

// 示例1
const name = 'a';
name = 'b'; // Uncaught TypeError: Assignment to constant variable.
// 示例2
const name = 'a';
const name = 'b';// Uncaught SyntaxError: Identifier 'name' has already been declared

所以如果定义了一个常量之后,再不小心被人覆盖重赋值的话,会报错,确保变量不被污染。
2.class 和 extends 和 super
ES6的这三个方法对应着ES5的原型、构造函数、继承。ES6提供了更接近传统的方法,引入了Class(类)的概念。新的 Class写法让对象原型的写法更加清晰、更加面向对象、更加通俗易懂。
如下代码所示:

class Person {
	constructor(name) {
		this.type = 'person';
		this.name = name;
	}
	eat(food) {
		console.log(this.name + ' of ' + this.type + ' eat ' + food);
	}
}

let John = new Person('John');
let Rose  = new Person('Rose');
John.study('apple'); // John of person eat apple
Rose.study('pear'); // Rose of person eat pear

示例首先用class关键字定义了一个”类”,类里有constructor关键字,constructor关键字定义的方法就是构造函数。而this关键字则代表示例对象。简单地说:constructor内定义的方法和属性是实例对象自己的,而constructor外定义的方法和属性则是所有实例对象可以共享的。
Class(类)之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承要清晰和方便很多。如下代码所示:

class Person {
	constructor(name) {
		this.type = 'person';
		this.name = name;
	}
	eat(food) {
		console.log(this.name + ' of ' + this.type + ' eat ' + food);
	}
}

class Student extends Person {
	constructor(name){
		super(name);
		this.type = 'student';
	}
	study(course) {
		console.log(this.name + ' of ' + this.type + ' study ' + course);
	}
}
let lilei = new Student('lilei');
let hanmeimei = new Student('hanmeimei');
lilei.study('math'); // lilei of student study math
hanmeimei.study('music'); // hanmeimei of student study music

示例中定义了一个Student类。该类使用extends关键字继承了Person类的所有属性和方法。
super关键字指代父类的实例(即父类的this对象),子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工,如果不调用super方法,子类就得不到this对象。
如下代码所示:

class Person {
	constructor() {
	}
	eat() {
	}
}

class Student extends Person {
	constructor(){
	}
	study() {
	}
}
let lilei = new Student(); // Uncaught ReferenceError: this is not defined

ES6的继承机制,实际上是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this.
3.arrow function
箭头函数最常用,用她来写function比原来的写法要简洁清晰很多,如下代码示例:

// ES5
function (i) {
	return i + 1;
}
// ES6

(i) => i + 1;

复杂函数如下:

// ES5
function (x, y) {
	x = y + 1;
	return x;
}
var add = function(x, y){
	return x + y;
}
add(2 ,3); //5
// ES6
(x, y) => {x = y + 1; return x;} 
let add = (x, y) => x + y;
add(2 ,3); //5

除了看起来简洁了以外,arrow function还解决了this对象指代混乱的问题。如下代码示例:

// 混乱
class Person{
	constructor(){
		this.type = 'person';
	}
	eat(food) {
		setTimeout(function() {
			console.log(this.type + ' eat ' + food);
		}, 1000)
	}
}
var John = new Person();
John.eat('apple'); // undefined eat apple
// 解决方案1
class Person{
	constructor(){
		this.type = 'person';
	}
	eat(food) {
		var self = this;
		setTimeout(function() {
			console.log(self.type + ' eat ' + food);
		}, 1000)
	}
}
var John = new Person();
John.eat('apple'); // person eat apple
// 解决方案2
class Person{
	constructor(){
		this.type = 'person';
	}
	eat(food) {
		setTimeout(function() {
			console.log(this.type + ' eat ' + food);
		}.bind(this), 1000)
	}
}
var John = new Person();
John.eat('apple'); // person eat apple 
// 使用arrow function
class Person{
	constructor(){
		this.type = 'person';
	}
	eat(food) {
		setTimeout(() => {
			console.log(this.type + ' eat ' + food);
		}, 1000)
	}
}
var John = new Person();
John.eat('apple'); // person eat apple

当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。并不是因为箭头函数内部有绑定this的机制,事件原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。
4.template string
当我们需要插入大段的HTML内容到文档中时,传统的写法非常麻烦,所以之前我们通常会引用一些模板工具库。代码如下:

$("#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!`);

用反引号(`)来标识起始,用${}来引入变量,而且所有的空格和缩进都会被保留在输出之中。
5.destructuring 解构
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这种被称为解构(destructuring)
如下示例:

// ES5
var name = 'name1';
var age = 20;
var c = {
	name: name,
	age: age
};
console.log(c); // Object {name: "name1", age: 20}
// ES6
let name = 'name1';
let age = 20;
let c = {name, age};
console.log(c); // Object {name: "name1", age: 20}
// ES6
let c = {name: "name1", age: 20};
let {name, age} = c;
console.log(name, age); // name1 20

6.default 和 rest
6.1.default
默认值。函数默认参数:

//ES5
function add(lens) {
	lens = lens || 1;
	console.log(lens);
}
add(); // 1
// ES6
function add (lens = 1) {
	console.log(lens);
}
add(); // 1
add(2); // 2

6.2.reset

// ES5
function add (params) {
	console.log(arguments);
}
add(1, 2, 3); // [1, 2, 3]
// ES6
function add (...params) {
	console.log(params);
}
add(1, 2, 3); // [1, 2, 3]

参考文章:
30分钟掌握ES6/ES2015核心内容

此条目发表在JavaScript, 未分类分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注