你的位置:首页 > Java教程

[Java教程]ES6的一些基本用法

 

● 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<script src="some.js" type="text/babel"></script>"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.radius*this.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); //39Math.trunc(0.5);//0Math.trunc(-0.3);//-0//数值类型检查Number.isNan(45)Number.isFinite();//SignMath.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);