ES6语法记录
1. import 和 export
看到别人的代码中有:
import dva from 'dva';
import { browserHistory } from 'dva/router';
import './utils/func';
import './index.html';
import './index.css';
这是怎么用的?
这是ES6的语法,举个例子:
假设 a.js 内容如下:
var sex="boy";
var echo=function(value){
console.log(value);
};
//通过 export 暴露对象给其他引用者
export {sex,echo};
// 还可以使用 export default命令,为模块指定默认输出
export default sex;
// 还可以
export {sex as sex_alias,echo as echo_alias};
export {sex as default,echo}
其实 export default sex
相当于为sex变量值"boy"起了一个系统默认的变量名default,自然default只能有一个值,所以一个文件内不能有多个export default
然后在 b.js 中引入
// 引入 a.js 中暴露的 default 内容,这里可以使用任意自定义的名称,
// 例如还可以 import anyYouWant from "./a.js";
import any from "./a.js";
//引入 a.js 中export的非默认的对象
import {sex,echo} from "./a.js";
import {sex as xxx} from "./a.js";
console.log(sex);
// 输出 boy , 这表示引入之后就可以使用 a.js 暴露的对象了
// 将./a.js'文件里的所有非默认组件,全部集结成一个Home模型组件,命名可以自定义,然后可以通过点语法,来使用组件里面的所有export的组件,
// 例如 componentA.sex
import * as componentA from "./a.js";
这里还有一个有意思的现象,被引入的js文件何时真正的被引入?
这个答案好像是 因为 import 是编译时执行的,不是运行时,所以在编译时它会检查这个import是否有效(有效的意思是import引入的内容在代码中有用到,否则你引入它也没有意义),如果有效,那么被引入的js文件就会被执行,否则它就不执行.
至于上面的 import dva from 'dva';
这种没有路径的应该从哪里找模块呢?
这个好像跟你的打包工具有关, roadhog 还是 webpack ?
import './utils/func';
表示直接执行引入的文件
1.1 再多写几句 require 和 import 的区别
require统治了ES6之前的所有模块化编程,即使现在,在ES6 module被完全实现之前,还是这样。
node的module遵循CommonJS规范,requirejs遵循AMD,seajs遵循CMD,虽各有不同,但总之还是希望保持较为统一的代码风格。
node 语法
module.exports = {
a : function() {},
b : 'xxx'
};
var m = require('./a');
m.a();
AMD or CMD 语法
define(function(require, exports, module){
module.exports = {
a : function() {},
b : 'xxx'
};
});
define(function(require, exports, module){
var m = require('./a');
m.a();
});
require 相当于module.exports的传送门,module.exports后面的内容是什么,require的结果就是什么,require理论上可以运用在代码的任何地方,甚至不需要赋值给某个变量之后再使用.
但是import则不同,它是编译时的(require是运行时的),它必须放在文件开头,而且使用格式也是确定的,不容置疑。它不会将整个模块运行后赋值给某个变量,而是只选择import的接口进行编译,这样在性能上比require好很多。
从理解上,require是赋值过程,import是解构过程,当然,require也可以将结果解构赋值给一组变量,但是import在遇到default时,和require则完全不同:var $ = require('jquery');
和 import $ from 'jquery'
是完全不同的两种概念。
Promise
为了解决"回调地狱",Promise 对象应运而生,在 EMCAScript 2015 当中已经成为标准.
新建Promise对象的大概语法如下
// 方法1
let promise = new Promise ( (resolve, reject) => {
if ( success ) {
resolve(a) // pending ——> resolved 参数将传递给对应的回调方法
} else {
reject(err) // pending ——> rejectd
}
} )
// 方法2
function promise () {
return new Promise ( function (resolve, reject) {
if ( success ) {
resolve(a)
} else {
reject(err)
}
} )
}
注意:实例化的Promise对象会立即执行
然后就可以使用 .then .catch 的链式语法,每一步都返回一个Promise对象(如果返回的不是Promise对象,好像会自动封装成Promise)
还提供了 Promise.all() 、 Promise.race() 、
// 当p1、p2、p3的状态都变成resolved时,promise才会变成resolved,并调用then()的已完成回调,但只要有一个变成rejected状态,promise就会立刻变成rejected状态
var promise = Promise.all( [p1, p2, p3] )
promise.then(
...
).catch(
...
)
// 参数中的p1、p2、p3只要有一个改变状态,promise就会立刻变成相同的状态并执行对于的回调
var promise = Promise.race( [p1, p2, p3] )
promise.then(
...
).catch(
...
)
async/await
例子
async function getMoviesFromApi() {
try {
let response = await fetch('https://facebook.github.io/react-native/movies.json');
let responseJson = await response.json();
return responseJson.movies;
} catch(error) {
console.error(error);
}
}
- async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
- await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try...catch 代码块中
- await 命令只能用在 async 函数之中,如果用在普通函数,就会报错
let
使用let声明的变量只在语句块内有效。
所以可以在任何块内重复声明
Arrow Function, Lambda表达式
在es6之前,通常这样定义和使用函数:
var helloWorld =function (name){
return "Hello, " + name ;
}
console.log(helloWorld("darren"));
es6中可以使用Lambda表达式:
var newGreeting = (name) => {
return "Hello, " + name ;
}
// 如果只有一条return语句,可以继续简化
var newGreeting = (name) => "Hello, " + name ;
// 如果只有一个参数,可以继续简化
var greeting = name=> "Hello " + name;
// 如果没有参数,可以写成:
var greeting = () => "Hello Darren";
console.log(helloWorld("darren"));
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 {x,y: myy, z: myz} = currentDate();
console.log(x);
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();
可变参数
es6之前,这样写
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", "1","2");
解构参数
对参数结构描述更明了
function logMessage(msg, {name: courseName, publisher: publisherName}){
console.log(msg + " " + courseName + " by " + publisherName);
}
logMessage("myMsg", {name:"myName",publisher:"myPublisher"});
解构数组
//赋值的时候解构
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);
// rest输出为一个数组 [3,4,5]
//嵌套数组的解构
var numbers_nested = [1, 2, [3, 4, 5]];
var [first, second, [third,,fifth]] = numbers_nested;
console.log(first);
console.log(second);
console.log(third);
解构对象
var course = {
name: "name",
publisher: "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);
}
String Templates
以前这样拼接字符串
var a = "Hello";
var greeting = a + ", World";
console.log(greeting);
ES6中可以这样写:
var a = "Hello";
var greeting = `${a} , World`;
console.log(greeting);
在``之内的接受空白、换行等,可以把变量放在${}
之内
``之内还可以作为参数传递给某个方法并分别取出字符串和变量:
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", raw: Array(2)]
[7]
// 总结
以上``之内的字符串按字符串常量和变量分割成两个数组
快速创建对象
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: '恒大'}
只读变量 const修饰符
Sets 集合
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
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);
}