【转】 更多请参考:ECMAScript6入门 ● let ● variable hoisting ● arrow Function, Lambda表达式 ● Destructuring Assignments 解构赋值 ● 默认参数值 Default Parameters ● 可变参数 ● 解构参数 ● 解构数组 ● 解构对象 ● 遍历 ● Generators ● String Templates ● 快速创建对象 ● 只读变量 ● Sets ● Maps ● Symbols ● WeakMaps ● Promises ● 创建类 ● Modules ● 内置函数
let
使用let声明的变量只在语句块内有效。
“use strict”;
function blockBindingDemo(){
let a = 123;
var b = 123;
if(true){
let a = 456;
b = 456;
console.log(“使用let语句块中的a为” +a);//456
console.log(“使用var语句块中的b为” +b)
}
console.log(“使用let语句块外的a为” +a);//123
console.log(“使用var语句块外的b为” +b);//456
}
blockBindingDemo();
以上,以let方式声明的变量只在语句块内有效,而以var方式的变量是一个全局变量。
variable hoisting
可以先初始化变量,再声明变量,如下是可以的: x=6; var x; console.log(x); 相当于: var x; x = 6; 变量首先得初始化,否则会呈现undefined var x = 5; console.log(x + “ “ + y); //5 undefined var y = 7; 因为在声明变量y之前还没有初始化,y还没有被hoisted。
Arrow Function, Lambda表达式
在es6之前,通常这样定义和使用函数:
var helloWorld = function(name, greeting){
return name + “ “ + greeting;
}
console.log(helloWorld(“darren”,”hello”));
es6中可以使用Lambda表达式:
var newGreeting = (name, greeting) => {
return name + “ “ + greeting;
}
console.log(newGreeting(“darren”,”hello”));
还可以简化成这样的写法:
var newGreeting = (name, greeting) => name + “ “ + greeting;
console.log(newGreeting(“darren”,”hello”));
如果只有一个参数,可以写成: var greeting = greeting => “Hello “ + greeting; 如果没有参数,可以写成: var greeting = () => “Hello Darren”; ■ 遍历一个数组,把数组内的元素变成大写。
var courses = [‘hello’,’world’];
cosnole.log(courses.map(course => {
return course.toUpperCase();
}))
■ 对数组排序。
var myArr = [2, 4.6];
var sortedArr = myArr.sort((a, b) => a < b ? 1 : -1);
console.log(sortedArr);
■ this的作用域。
function Course(){
this.name = “”;
this.description = “”;
this.author = “”;
this.getSummary = function(){
return this.name + “, “ + this.description;
};
this.getDetails = fuction(){
window.setTimeout(() => {console.log(this.getSummary() + “ “ + this.author)},1000);
}
}
var course = new Course();
course.getDetails();
以上,this的作用域指的是Course,而不是window。也就是说,lambda表达式中的this的作用域的指向取决于在哪里定义,而不是取决于在哪里使用。
Destructuring Assignments 解构赋值
es6之前这样写: var x=1,y=2,z=3; 现在可以这样写: var [x, y, z] = [1, 2, 3]; [y,z] =[z,y]; ■ 从数组中解构赋值
function getDate(){
return [15,07,2015];
}
var [x, y] = getDate();
var [,,z] = getDate();
console.log(x);
console.log(y);
console.log(z);
■ 从对象中解构赋值
function currentDate(){
return {x:1, y:2, z:3};
}
var {y: myy, z: myz} = currentDate();
console.log(myy);
console.log(myz);
默认参数值 Default Parameters
es6之前,这样写默认参数值:
function sayHi(firstname, lastname){
firstname = firstname || “darren”;
lastname = lastname || “ji”;
console.log(firstname + “ “ + lastname);
}
sayHi();
现在可以这么写:
function sayHi(firstname=”darren”,lastname=”ji”){
console.log(firstname + “ “ + lastname);
}
sayHi();
可变参数
把可变参数拼接成字符串,以前这样写:
function joinArgus(){
return Array.prototype.slice.call(arguments).join(‘ ‘);
}
var result = joinArgus(‘hello’,’world’ );
console.log(result);
现在可以这么写:
function joinArgus(…words){
return words.join(‘ ‘);
}
var result = joinArgus(‘’,’’);
console.log(result);
可以结合Spread Operator来处理可变参数。
function logMessages(message, …args){
console.log(message, …args);
}
logMessages(“he %s : %s”, “”,””);
解构参数
function logMessage(msg, {name: courseName, publisher: publisherName}){
console.log(msg + “ “ + courseName + “ by “ + publisherName);
}
logMessage(“”, {name:””,publisher:””});
解构数组
//赋值的时候解构
var numbers = [1, 2, 3, 4, 5];
var [first, second, third, , fifth] = numbers;
console.log(fifth);
//使用参数的时候解构
function arrayDestructuring([first, second,…rest]){
console.log(first);
console.log(second);
console.log(rest);
}
arrayDestructuring(numbers);
//嵌套数组的解构
var numbers_nested = [1, 2, [3, 4, 5]];
var [first, second, [third,,fifth]] = numbers_nested;
console.log(first);
console.log(second);
console.log(third);
解构对象
引用如下:
browser.min.js
“use strict”;
var course = {
name: “”,
publisher: “”
};
function courseDetails(course){
let {name, publisher} = course;
console.log(name + “ “ + publisher);
}
courseDetails(course);
遍历
“use strict”;
var words = [‘’,’’,’’];
//输出键和值
for(let word of words.etrieis()){
console.log(word);
}
//输出值
for(let word of words.values()){
console.log(word);
}
//输出键
for(let word of words.keys()){
console.log(word);
}
Generators
有以下的一个Generator的写法:
function* greet(){
console.log(调用了greet方法
);
}
greet();
显示结果: 什么都不显示 按照以往调用函数的方式调用,结果什么都不显示。greet()到底是什么呢?不妨打印出一探究竟。
function* greet(){
console.log(调用了greet方法
);
}
let greeter = greet();
console.log(greeter);
显示结果: {next:[Function], throw:[Function]} 原来,当调用greet()的时候并没有执行方法,而是返回一个object对象。 既然next是greet()返回结果中的一个函数,那就调用next()。
function* greet(){
console.log(调用了greet方法
);
}
let greeter = greet();
let next = greeter.next();
console.log(next);
显示结果: 调用了greet方法 {value:undefined, done: true} value:undfined说明还没有从generator中返回任何值,done:true说明yield已经被执行,这里是null。 yield到底是什么?
function* greet(){
console.log(调用了greet方法
);
yield “hello”;
}
let greeter = greet();
let next = greeter.next();
console.log(next);
显示结果: 调用了greet方法 {value:’hello’, done: false} value:’hello’说明yield返回一个hello值, done:false说明yield还没被执行。如果再执行一次next方法会怎样?
function* greet(){
console.log(调用了greet方法
);
yield “hello”;
}
let greeter = greet();
let next = greeter.next();
console.log(next);
let done = greeter.next();
console.log(done);
显示结果: 调用了greet方法 {value:’hello’, done: false} {value:undefined, done:true} 可见,当第一次执行next方法时,yield返回hello,但还没真正执行yield语句;当第二次执行next方法时,执行了yield语句,value再次变为undefined。 ● 多个yield语句 如果有多个yield语句呢?
function* greet(){
console.log(`Generators会延迟加载,第一次调用next方法时执行`);
yield “How”;
console.log(第二次调用next方法时执行
);
yield “are”;
console.log(第三次调用next方法时执行
);
}
var greeter = greet();
console.log(greeter.next());
console.log(greeter.next());
console.log(greeter.next());
结果: Generators会延迟加载,第一次调用next方法时执行 {value: ‘How’, done:false} 第二次调用next方法时执行 {value: ‘are’, done:false} 第三次调用next方法时执行 {value: undefined, done:true} 还可以通过遍历greet()来分别执行。
function* greet(){
console.log(`Generators会延迟加载,第一次调用next方法时执行`);
yield “How”;
console.log(第二次调用next方法时执行
);
yield “are”;
console.log(第三次调用next方法时执行
);
}
var greeter = greet();
for(let word of greeter){
console.log(word);
}
结果: Generators会延迟加载,第一次调用next方法时执行 How 第二次调用next方法时执行 are 第三次调用next方法时执行 可见,greet()集合的集合元素是每一个yield的返回值,也就是调用next方法后返回对象中的value字段对应的值。 也就是按如下写也能获取相同的返回结果:
function* greet(){
console.log(`Generators会延迟加载,第一次调用next方法时执行`);
yield “How”;
console.log(第二次调用next方法时执行
);
yield “are”;
console.log(第三次调用next方法时执行
);
}
var greeter = greet();
console.log(greeter.next().value);
console.log(greeter.next().value);
console.log(greeter.next().value);
● yield赋值
function* greet(){
let a = yield “first”;
console.log(a);
yield “second”;
}
var greeter = greet();
console.log(greeter.next().value);
console.log(greeter.next().value);
结果: first undefined second 而预期的结果是: first first second 真实的结果和预期的结果不一样,yield语句并不能赋值。那么,变量a该如何赋值呢?
function* greet(){
let a = yield “first”;
console.log(a);
yield “second”;
}
var greeter = greet();
console.log(greeter.next().value);
console.log(greeter.next(‘给上一个yield中的变量a赋的值’).value);
结果: first 给上一个yield中的变量a赋的值 second 所以,通过next方法可以给上一个yield语句中的变量赋值。 再看一个yield赋值的例子。
function* greet(){
let a = yield “first”;
a = yield a + “hello”;
yield a + “hello”;
}
var greeter = greet();
console.log(greeter.next().value);
console.log(greeter.next(“first”).value);
console.log(greeter.next(“second”).value);
结果: first firsthello secondhello → 当执行console.log(greeter.next().value);时,把第一个yield的返回结果first打印出来。 → 当执行console.log(greeter.next(“first”).value);先把first赋值给上一个yield,即第一个yield中的变量a,打印出firsthello。 → 当执行console.log(greeter.next(“second”).value);先把second赋值给上一个yield,即第二个yield中的变量a,打印出secondhello。
String Templates
以前这样拼接字符串。 var a = “Hello”; var greeting = a + “, World”; console.log(greeting); ES6中可以这样写: var a = “Hello”; var greeting = ${a} , World
; console.log(greeting); 在之内的接受空白、换行等,可以把变量放在${}之内。 var msg = \`it's time ${new Date().getHours()}, I'm sleeping\`; console.log(msg);
之内还可以作为参数传递给某个方法并分别取出字符串和变量:
function conclude(strings, …values){
console.log(strings);
console.log(values);
}
conclude`it’s time ${new Date().getHours()} I’m sleeping`;
结果: it’s time , I’m sleeping 20 以上之内的字符串自动拼接以逗号分隔,
之内变量赋值给 values。
快速创建对象
_let firstName = “Darren”;_ _let lastName = “Ji”; let person = {firstName, lastName}; console.log(person);_ 结果: {firstName: ‘Darren’, lastName: ‘Ji’} 甚至可以创建嵌套对象。 let firstName = “Darren”; let lastName = “Ji”; let person = {firstName, lastName}; let teamName = “恒大”; let team = {person, teamName}; console.log(team); 结果: {person:{firstName: ‘Darren’, lastName: ‘Ji’}, teamName: ‘恒大’}
只读变量
变量值通常可以改变: let a = 100; a = 200; console.log(a); ES6中多了一个修饰符const,把变量设置成只读。 const val = ‘hi’; val = ‘yes’; console.log(val);
Sets
ES6使用Set类构造集合。 let s = new Set([10, 20, 30]); s.add(40); console.log(s); s.delete(30); console.log(s); 结果: [10, 20, 30, 40] [10, 20, 40]
Maps
ES6使用Map类处理键值对集合。
var map = new Map();
var myKey = {name: ‘darren’};
map.set(myKey, ‘my favorite book’);
//是否包含某键
console.log(map.has(myKey));
//根据键获取值
console.log(map.get(myKey));
//遍历值
for(var item of map.values()){
console.log(item);
}
结果: true my favorite book my favorite book
Symbols
ES6是唯一、不可变的,使用Symbol类创建Symbol实例。 Symbol可以作为键。
let a = new Map();
{
let key = Symbol();
a.set(key, ‘book’);
console.log(a.get(key));
}
Symbol还可以作为对象的字段。
let courseName = Symbol();
let course = {
publisher: ‘hd’,
[courseName]: ‘lesson’
};
console.log(course);
结果: {publisher: ‘hd’, Symbol(): ‘lesson’} 如果想遍历Couse对象的字段,Symbol()是获取不到的。使用这一特点可以隐藏某些信息。
let courseName = Symbol();
let course = {
publisher: ‘hd’,
[courseName]: ‘lesson’
};
console.log(course);
var props = [];
for(var c in course){
props.push(c);
}
console.log(props.length);
console.log(props);
结果: {publisher: ‘hd’, Symbol(): ‘lesson’} 1 publisher 但可以通过以下方式获取到Symbol以及对应的值。 console.log(Object.getOwnPropertySymbols(course)[0]); let keySymbol = Object.getOwnPropertySymbols(course)[0]; console.log(course[keySymbol]);
WeakMaps
不能使用字符串作为键。键只能是对象、函数。
var w = new WeakMap();
var course = {name: ‘t’, publisher:’hd’};
var company = {name: ‘sup’};
w.set(course, {price:59});
w.set(company, ‘s’);
console.log(w.has(course));
w.delete(course);
w.clear(course);
console.log(w.get(company));
Promises
fetch(“http://services.odata.org/V4/Northwind/Northwind.svc/",{
method: ‘get’
}).then(function(response){
return response.json();
}).then(function(data){
console.log(data.value);
}).catch(function(){
console.log(‘failed’);
});
还可以这么写:
var promise = new Promise(function(resolve, reject){
$.ajax(“http://services.odata.org/V4/Northwind/Northwind.svc/",{
success: function(data){
resolve(data);
},
error: function(){
reject(“Error”);
}
})
});
promise.then(function(result){
console.log(result);
}, function(err){
console.log)(err);
});
//如果有多个promise
//Promise.all([promise]).then(function(results){
//results[0] results[1] …
},function(){
})
//Promise.race([promise]);
//Promise.reject(reason);
创建类
class Shape{
constructor(w,l){
this.w = w;
this.l = l;
}
render(){
console.log(“开始构建图形…”)
}
}
class Circle extens Shape{
constructor(w, l, radius){
super(w, l);
this.radius = radius;
}
static getpi(){
return 3014;
}
get area(){
return Circle.pi this.radiusthis.radius;
}
render(){
console.log(“正在构建圆形…”);
}
}
var obj = new Circle(0, 0, 20);
obj.l = 40;
obj.render();
Modules
Module中的函数除非使用export,否则对外不可用。使用import使用某个函数。 ● 通过export方法导出函数 addition.js
function sum(a, b){
return a + b;
}
function sumThree(a, b, c){
return a + b + c;
}
export {sum, sumThree};
main.js
import {sum, sumThree} from ‘addition’
console.log(sum(2,3));
console.log(sumTrhee(2, 3, 4));
● 通过函数上的export方法导出 addition.js
export function sum(a, b){
return a + b;
}
export function sumThree(a, b, c){
return a + b + c;
}
● 导入函数使用别名 main.js
mport {sum as addTwoNumbers,
sumThree} from ‘addition’;
console.log(addTwoNumbers(2,3));
console.log(sumTrhee(2, 3, 4));
● 给导入的函数统一的命名空间。
import * as addition from ‘addition’;
import {sum as addTwoNumbers,
sumThree} from ‘addition’;
console.log(addition.sum(2,3));
console.log(addition.sumTrhee(2, 3, 4));
内置函数
//字符串
conole.log(‘ha’.repeat(2));
console.log(“world”.includes(“rl”));
console.log(“Skill”.startsWith(“Skill”));
console.log(“Hello”.endsWith(“lo”));
//遍历字符串
for(var ch of ‘hello’){
console.log(ch);
}
//近似值检查
Math.trunc(39.7); //39
Math.trunc(0.5);//0
Math.trunc(-0.3);//-0
//数值类型检查
Number.isNan(45)
Number.isFinite();
//Sign
Math.sign();
//数值安全性检查
Number.isSafeInteger(42);
//过滤数组
var result = [“”,””,””].find(x => x == “”);
console.log(result);
//从某个源获取数组
var result = Array.from(document.querySelectorAll(‘*’));
console.log(result);
//从Map从获取数组
var m = new Map([[1,2],[2,4],[4,8]]);
console.log(Array.from(m));
//从字符串中获取数组
console.log(Array.from(“hello”));
//创建数组
var arr = Array.of(1, 2, 3);
//其它数组方法
[0, 0, 0].fill(7, 1);
[1, 2, 3].findIndex( x => x == 2);
[1, 2, 3, 4, 5].copyWithin(3, 1);
//对象属性赋值
//{distance:40, duration:20, interval:10, start:0}
var first = {start:0};
var second = {interval:10, duration:20};
var third = {distance: 40};
Object.assign(first, second, third);
console.log(first);