不定参数是在函数中使用命名参数同时接收不定数量的未命名参数。这只是一种语法糖,在以前的JavaScript代码中我们可以通过arguments变量来达到这一目的。不定参数的格式是三个句点后跟代表所有不定参数的变量名。
比如下面这个例子中,…x代表了所有传入add函数的参数。
// 将所有参数相加的函数 function add(...x) { return x.reduce((m,n) => m+n); } // 传递任意个数的参数 console.log(add(1,2,3)); // 输出:6 console.log(add(1,2,3,4,5)); // 输出:15
拓展参数
拓展参数则是另一种形式的语法糖,它允许传递数组或者类数组直接做为函数的参数而不用通过apply。
var people = ['Wayou','John','Sherlock']; // sayHello函数本来接收三个单独的参数人一,人二和人三 function sayHello(people1, people2, people3) { console.log(`Hello${people1}, ${people2}, ${people3}`); } // 但是我们将一个数组以拓展参数的形式传递,它能很好地映射到每个单独的参数 sayHello(...people); // 输出:Hello Wayou,John,Sherlock // 而在以前,如果需要传递数组当参数,我们需要使用函数的apply方法 sayHello.apply(null, people); // 输出:Hello Wayou,John,Sherlock
let与const 关键字
可以把let看成var,只是它定义的变量被限定在了特定范围内才能使用,而离开这个范围则无效。const则很直观,用来定义常量,即无法被更改值的变量。
for (let i=0; i<2; i++) { console.log(i); // 输出: 0,1 } console.log(i); // 输出:undefined,严格模式下会报错
for of 值遍历
我们都知道for in循环用于遍历数组,类数组或对象,ES6中新引入的for of循环功能相似,不同的是每次循环它提供的不是序号而是值。
var someArray = ["a","b","c"]; for (v of someArray) { console.log(v); // 输出 a,b,c }
iterator, generator
1.iterator: 它是这么一个对象,拥有一个next方法,这个方法返回一个对象{done,value},这个对象包含两个属性,一个布尔类型的done和包含任意值的value
2.iterable: 这是这么一个对象,拥有一个obj[@@iterator]方法,这个方法返回一个iterator
3.generator: 它是一种特殊的iterator。反的next方法可以接收一个参数并且返回值取决与它的构造函数(generator function)。generator同时拥有一个throw方法
4.generator函数: 即generator的构造函数。此函数内可以使用yield关键字。在yield出现的地方可以通过generator的next或throw方法向外界传递值。generator 函数是通过function*来声明的
5.yield关键字:它可以暂停函数的执行,随后可以再进进入函数继续执行
模块
在ES6标准中,JavaScript原生支持module了。这种将JS代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如CommonJS和AMD模式。
将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。
// point.js module "point" { export class Point { constructor(x,y) { public x=x; public y=y; } } } // myapp.js // 声明引用的模块 module point from "/point.js"; // 这里可以看出,尽管声明了引用的模块,还是可以通过指定需要的部分进行导入 import Point from "point"; var origin = new Point(0,0); console.log(origin); Map,Set 和 WeakMap,WeakSet
这些是新加的集合类型,提供了更加方便的获取属性值的方法,不用像以前一样用hasOwnProperty来检查某个属性是属于原型链上的呢还是当前对象的。同时,在进行属性值添加与获取时有专门的get,set方法。
// Sets var s = new Set(); s.add("hello").add("goodbye"); s.size === 2; s.has("hello") === true; // Maps var m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) == 34; 有时候我们会把对象作为一个对象的键用来存放属性值,普通集合类型比如简单对象会阻止垃圾回收器对这些作为属性键存在的对象的回收,有造成内存泄漏的危险。而WeakMap,WeakSet则更加安全些,这些作为属性键的对象如果没有别的变量在引用它们,则会被回收释放掉,具体还看下面的例子: // Weak Maps var wm = new WeakMap(); wm.set(s, {extra: 42}); wm.size === undefined // 对象释放了 // Weak Sets var ws = new WeakSet(); ws.add({data: 42}); // 因为添加到ws的这个临时对象没有其他变量引用它,所以ws不会保存它的值,也就是说这次添加其实没有意思 Proxies Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。一下子让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处。 // 定义被侦听的目标对象 var engineer = {name: 'Joe Sixpack', salary: 50}; // 定义处理程序 var interceptor = {set: function(receiver, property, value) { console.log(property, 'is changed to', value); receiver[property] = value; } }; // 创建代理以进行侦听 engineer = Proxy(engineer, interceptor); //做一些改动来触发代理 engineer.salary = 60; // 控制台输出:salary is changed to 60