编译时加载
ES6模块不是对象,而是通过export命令显式指定输出的代码,输入时也采用静态命令的形式。
// ES6模块
import { stat, exists, readFile } from 'fs';
上面代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”,即ES6可以在编译时就完成模块加载,效率要比CommonJS模块的加载方式高。当然,这也导致了没法引用ES6模块本身,因为它不是对象。
函数
默认参数
可以直接在默认参数中调用函数,但当函数提供实参时,默认参数并不会直接调用函数,而是使用实参:
function addValue(a,b){
return a+b;
}
function add(a,b=addValue(1,2)){
return a+b;
}
console.log(add(1,2));//3
console.log(add(1));//4
function foo(x = 3) {
console.log( x );
}
foo(); // 3
foo( undefined ); // 3
foo( null ); // null
foo( 0 ); // 0
ES6函数参数变量是默认声明的,所以不能用let或const再次声明。默认参数只有当传入的值是undefined时,才会生效
剩余参数rest和扩展运算符
一个函数只能有一个剩余参数,且必须放在最后面。设计剩余参数的目的是用来替代 ECMAScript 中的 arguments。
扩展运算符好比rest的逆运算,用于将数组转为用逗号分隔的参数序列,而剩余参数允许你把多个独立的参数整合到一个数组中。
rest参数的形式为:...变量名;扩展运算符是三个点(...)
比如,在使用Math.max计算一个数组中最大的数:
let value = [1,10,100,-1000];
Math.max.apply(null,value);//100
//使用扩展运算符
console.log(Math.max(...value));//100
args 无论是不是空的,它永远是一个数组。但它不包含已经命名的 x,y 和 z 参数,只会包含超出前三个值的传入参数。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中:
function foo(x,y,z,...args) {
console.log( x, y, z, args );
}
foo(); // undefined undefined undefined []
foo( 1, 2, 3 ); // 1 2 3 []
foo( 1, 2, 3, 4 ); // 1 2 3 [ 4 ]
foo( 1, 2, 3, 4, 5 ); // 1 2 3 [ 4, 5 ]
function bar(...args) {
console.log( args[3] );//4
console.log(args);//[1, 2, 3, 4, 5]
}
var arr = [ 1, 2, 3, 4, 5 ];
bar( ...arr );
bar( arr );// args => [[1,2,3,4,5]]; ...args => [1,2,3,4,5]
在形参列表,它把实参整合。在实参列表,它把实参展开。
扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。扩展运算符用于对象中,等同于Object.assign():
let obj = {name: 'trigkit4', age: 23};
console.log({...obj});// {name: 'trigkit4', age: 23}
rest参数和arguments对象的区别
-rest参数只包含那些没有对应形参的实参;而 arguments 对象包含了传给函数的所有实参。
解构赋值
解构也可以设置默认值:
const getUserName = () => {
return {
name1: 'mike',
name2: 'jake'
};
};
const {name1, name3 = 'trigkit4'} = getUserName();
name3;//trigkit4
//结构数组可跳过其中某几项
const browserSet = ['chrome','safari','firefox','edge'];
const [b1,b2,,b3] = browserSet;
b1;//chrome
b3;//edge
//设置默认值
function getAges(
{age1=10,age2=20} = {}
){
console.log(age1,age2)
}
getAges({});//10 20
function getAge(
{age1,age2} = {age1:1,age2:2}
){
console.log(age1,age2)
}
getAge();//1,2
getAge({});//undefined undefined
getAge({age1:3});//3 undefined
new Set与数组去重
Set 内无重复的值
const arr = [...new Set([1, 2, 3, 3, NaN, NaN])]
// [1, 2, 3, NaN]
对象字面量
const name = 'Jane';
const age = 20
const person = {
[name]: true,
[age]: true
}
//Object {20: true, Jane: true}
箭头函数
箭头函数不属于普通的 function,所以没有独立的上下文。箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域(如果没有就是全局)。如果你在箭头函数中使用了this,那么该this一定就是外层的this。箭头函数会继承当前上下文的 this 关键字。
const person = {
name: 'trigkit4',
getName: () => this.name
}
// 编译结果却是
'use strict';
var person = {
name: 'trigkit4',
getName: function getName() {
return undefined.name;
}
};
该箭头函数的外层作用域是window对象,在ES6中,会默认采用严格模式,因此this也不会自动指向window对象了,而箭头函数本身并没有this,因此this就只能是undefined
在以下场景中不要使用箭头函数去定义:
-定义对象方法、定义原型方法、定义构造函数、定义事件回调函数。
箭头函数没有arguments对象,但可以使用rest参数:
let fn = (a,b) =>{
console.log(arguments)
}
fn(1,2);//arguments is not defined
let fn = (...args) =>{
console.log(...args)
}
fn(1,2);//1 2
箭头函数会继承当前上下文的 this 关键字
//例如:
[1,2,3].map( x => x + 1 )
//等同于:
[1,2,3].map((function(x){
return x + 1
}).bind(this))
import 和require
import 不能和 module.exports 一起用,能用的话就可以修改 export 的内容了。
- import必须放在文件最顶部,require不需要;
- import和export最终会被babel编译成
require和module.exports。所以import一个文件的时候,是同步的。会按照import顺序输出该值。
- CommonJS允许你动态加载模块,es6不允许。
let和const
let不会向window分配任何内容:
let me = "go"; // 全局作用域
console.log(window.me); //undefined
const
const是只读变量。const 对象仍然可以被改变的。
const abc = {a: 'a'};
abc.a = 'b';
console.log(abc);//Object {a: "b"}
Promise
如果一个 promise 失败,all和race也将 reject(拒绝)。
var p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("1"), 1001)
})
var p2 = new Promise((resolve, reject) => {
setTimeout(() => reject("2"), 1)
})
Promise.race([p1, p2]).then((res) => {
console.log("success" + res)
}, res => {
console.log("error " + res)
})
Promise.all([p1, p2]).then((res) => {
console.log("success" + res)
}, res => {
console.log("error " + res)
})
//error 2
//error 2
Generator 函数
Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。
var go = function*(){
yield 1;
yield 2;
yield 3;
};
[...go()] // [1, 2, 3]
for...of循环可以使用的范围包括数组、Set 和 Map 结构、类数组对象(比如arguments对象、DOM NodeList 对象)以及 Generator 对象和字符串
编译时加载
ES6模块不是对象,而是通过export命令显式指定输出的代码,输入时也采用静态命令的形式。上面代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”,即ES6可以在编译时就完成模块加载,效率要比
CommonJS模块的加载方式高。当然,这也导致了没法引用ES6模块本身,因为它不是对象。函数
默认参数
可以直接在默认参数中调用函数,但当函数提供实参时,默认参数并不会直接调用函数,而是使用实参:
ES6函数参数变量是默认声明的,所以不能用let或
const再次声明。默认参数只有当传入的值是undefined时,才会生效剩余参数rest和扩展运算符
一个函数只能有一个剩余参数,且必须放在最后面。设计剩余参数的目的是用来替代 ECMAScript 中的 arguments。
扩展运算符好比rest的逆运算,用于将数组转为用逗号分隔的参数序列,而剩余参数允许你把多个独立的参数整合到一个数组中。
rest参数的形式为:
...变量名;扩展运算符是三个点(...)比如,在使用
Math.max计算一个数组中最大的数:args 无论是不是空的,它永远是一个数组。但它不包含已经命名的 x,y 和 z 参数,只会包含超出前三个值的传入参数。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中:
在形参列表,它把实参整合。在实参列表,它把实参展开。
扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。扩展运算符用于对象中,等同于
Object.assign():rest参数和
arguments对象的区别-
rest参数只包含那些没有对应形参的实参;而arguments对象包含了传给函数的所有实参。arguments对象不是一个真实的数组;而rest参数是真实的 Array 实例。arguments对象对象还有一些附加的属性 (比如callee属性)。解构赋值
解构也可以设置默认值:
new Set与数组去重
Set 内无重复的值
对象字面量
箭头函数
箭头函数不属于普通的 function,所以没有独立的上下文。箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域(如果没有就是全局)。如果你在箭头函数中使用了this,那么该this一定就是外层的this。箭头函数会继承当前上下文的 this 关键字。
该箭头函数的外层作用域是window对象,在ES6中,会默认采用严格模式,因此this也不会自动指向window对象了,而箭头函数本身并没有this,因此this就只能是undefined
在以下场景中不要使用箭头函数去定义:
-定义对象方法、定义原型方法、定义构造函数、定义事件回调函数。
箭头函数没有arguments对象,但可以使用rest参数:
箭头函数会继承当前上下文的 this 关键字
import 和require
import 不能和
module.exports一起用,能用的话就可以修改 export 的内容了。require和module.exports。所以import一个文件的时候,是同步的。会按照import顺序输出该值。let和const
let不会向window分配任何内容:
const是只读变量。const 对象仍然可以被改变的。
Promise
如果一个 promise 失败,all和race也将 reject(拒绝)。
Generator 函数
Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。
for...of循环可以使用的范围包括数组、Set 和 Map 结构、类数组对象(比如arguments对象、DOM NodeList 对象)以及 Generator 对象和字符串