ECMAScript6特性es6

最常用的ES6特性:
        1.声明:let, const, 
        2.类:class, extends, super,
        3.箭头函数: arrow functions,
        4.字符模板: template string, 
        5.解构:destructuring, 
        6.参数默认值:default, rest arguments
        'use strict';   //声明严格模式   声明后没有var的变量报错
let和const声明:
    1.let声明:此声明是有块级作用域的,并且此方法不存在变量提升现象,变量一定要在声明后使用。
    {   let a = 10;  var b = 1}
    a // ReferenceError: a is not defined.  报错
    b // 1

    for循环的计数器,就很合适使用let命令。
    for (let i = 0; i < 10; i++) {}
    console.log(i);
    //ReferenceError: i is not defined

    2.const声明:声明一个只读的常量。一旦声明,常量的值就不能改变。
    const PI = 3.1415;
    PI // 3.1415
    PI = 3;
    // TypeError: Assignment to constant variable. //上面一旦声明就不能改变否则报错。
变量的赋值
    1.数组的赋值:
    //  以前:
    var a = 1;
    var b = 2;
    var c = 3;
    //  现在:
    var [a, b, c] = [1, 2, 3];
class,类的概念:
    class Animal {
        constructor(){    
        //  constructor 里面定义的属性和方法是自己的 ,而这个之外定义的属性方法是可以共享的。
            this.type = 'animal'
        }
        says(say){
            console.log(this.type + ' says ' + say)
        }
    }
    let animail = new Animal(); 构造函数
    animal.says('hello') 

    class Cat extends Animal {   //extends 这个方法可以是Cat 继承 Animal 上的属性和方法。。
        constructor(){
            super()
            this.type = 'cat'
        }
    }
    let cat = new Cat()
    cat.says('hello') //cat says hello
arrow function:箭头函数
    ES5function(i){ return i + 1; }function(x, y) {
        x++;
        y--;
        return x + y;
    }

    ES6(i) => i + 1                      (x, y) => {x++; y--; return x+y}//  超级无敌特性 无需在意this指向 因为ES6箭头函数没有自己的this,它的this是通过继承得来的

    ES5class Animal {
        constructor(){
            this.type = 'animal'
        }
        says(say){
            setTimeout(function(){
                console.log(this.type + ' says ' + say)    
              //这个构造函数会报错 因为setTimeout的this指向全局,以往方法会用到var that = this;而ES6就不必这样麻烦了。
            }, 1000)
        }
    }
     var animal = new Animal()
     animal.says('hi')   //undefined says hi


    ES6class Animal {
        constructor(){
            this.type = 'animal'
        }
        says(say){
            setTimeout( () => {
                console.log(this.type + ' says ' + say)
            }, 1000)
        }
    }
     var animal = new Animal()
     animal.says('hi')  //animal says hi
template string:模板字符串 ``反引号和${ };代替繁琐的+号引用变量
    ES5:  $("#result").append(
          "There are <b>" + basket.count + "</b> " +
           "items in your basket, " +
           "<em>" + basket.onSale +
           "</em> are on sale!"
    );
    ES6:  $("#result").append(`
            There are <b>${basket.count}</b> items
            in your basket, <em>${basket.onSale}</em>
            are on sale!
    `);
destructuring :ES6解构赋值
    //  ES5 : 
    let cat = 'ken'
    let dog = 'lili'
    let zoo = {cat: cat, dog: dog}
    console.log(zoo)  //Object {cat: "ken", dog: "lili"};
    //  ES6: 
    let cat = 'ken'                                           
    let dog = 'lili'
    let zoo = {cat, dog}
    console.log(zoo)  //Object {cat: "ken", dog: "lili"};
    //  也可以这样:
    let dog = {type: 'animal', many: 2}
    let { type, many} = dog
    console.log(type, many)   //animal 2
函数参数默认值:default, …rest
    //  ES5:
    function animal(type){
        type = type || 'cat'  
        console.log(type)
    }
    animal()//  ES6:
    function animal(type = 'cat'){  //直接在这里写默认值
        console.log(type)
    }
    animal()//  rest语法也很简单,直接看例子:
    function animals(...types){     // 这里几个点就是几个参数
        console.log(types)
    }
    animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]  //直接传几个参数 返回一个数组
深拷贝实现方式
    //  手动复制方式,如上面的代码,缺点就是
    Object.assign,ES6 的新函数,可以帮助我们达成跟上面一样的功能。
    obj1 = { a: 10, b: 20, c: 30 };
    obj2 = Object.assign({}, obj1);
    obj2.b = 100;
    console.log(obj1);
    // { a: 10, b: 20, c: 30 } <-- 沒被改到
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }
Promise

Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用“成功”和“失败”来描述并不准确,按照标准来讲,resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。不过在我们开始阶段可以先这么理解,后面再细究概念。


ECMAScript 6入门(记录 || 摘录笔记之阮一峰大神)【以下内容较长,围观者请勿靠近】

<script type="module"> 声明这个浏览器就可以支持es6了,不需要babel。
(经测试,import和export等什么不行艾…)当设置为这个后浏览器会失去跨域特性,必须同源
<script type="text/ecmascript6"></script>论坛里看到有人说直接设置为此也可支持es6语法高亮
(经测试,phpstorm可以,报错消失,其他编辑器并未有什么卵用~~)
博友可下载:ES6语法高亮的插件—JavaScriptNext

try{}catch{}finally{}
    对的执行try,否则抛出错误catch,throw可以自定义错误,catch的err可以接受到;最后执行finally
    Error对象有两个属性:name属性表示例外的类型,message属性表示例外的含义。根据这些属性的取值,我们可以决定处理例外的方式
				if(err.name == "SyntaxError") alert("Invalid expression")
		     else alert("Cannot uate")
				Error.name的取值一共有六种,如下:
						  Error:()的使用与定义不一致
						  RangeError:数值越界
						  ReferenceError:非法或不能识别的引用数值
						  SyntaxError:发生语法解析错误
						  TypeError:操作数类型错误
						  URIError:URI处理函数使用不当
		let [head, ...tail] = [1, 2, 3, 4];    后面的...相当于是二维数组
		变量的解构赋值:let [foo] = 1;  let [foo] = false;  后面必须是数组,其他类型全部报错
		let [x, y = 'b'] = ['a']; // x='a', y='b'    
        //   解构赋值默认值   ES6 内部使用严格相等运算符(===),{ 默认值生效的条件是,对象的属性值严格等于undefined。}
字符串:
		ES6 对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符。"\u{41}\u{42}\u{43}"     // "ABC"   大括号表示法与四字节的 UTF-16 编码是等价的。
		codePointAt方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下。
		JavaScript 内部,字符以 UTF-16 的格式储存,每个字符固定为2个字节。对于那些需要4个字节储存的字符(Unicode 码点大于0xFFFF的字符),JavaScript 会认为它们是两个字符。
		ES6 提供了codePointAt方法,能够正确处理 4 个字节储存的字符,返回一个字符的码点。
		ES6 提供了String.fromCodePoint方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode方法的不足
		ES6 为字符串添加了遍历器接口     for of{  这个遍历器最大的优点是可以识别大于0xFFFF的码点   }
		ES6	at()	'a'.at(0) // "a";	ES5 对字符串对象提供charAt方法,返回字符串给定位置的字符。该方法不能识别码点大于0xFFFF的字符。
		ES6 提供字符串实例的normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。
		'\u01D1'.normalize() === '\u004F\u030C'.normalize()
		ES6 又提供了三种新方法。JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中
					includes():返回布尔值,表示是否找到了参数字符串。
					startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
					endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
					这三个方法都支持第二个参数,表示开始搜索的位置。let s = 'Hello world!';      s.startsWith('world', 6) // true
		repeat方法返回一个新字符串,表示将原字符串重复n次。'hello'.repeat(2.9) // "hellohello"  【参数如果是小数,会被取整。】如果repeat的参数是负数或者Infinity,会报错。
		ES6 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。
					'x'.padStart(5, 'ab') // 'ababx'        'x'.padStart(4, 'ab') // 'abax'
正则:
		new RegExp(/abc/ig, 'i').flags		// "i"
		上面代码中,原有正则对象的修饰符是ig,它会被第二个参数i覆盖
		字符串对象共有 4 个方法,可以使用正则表达式:match()、replace()、search()和split()
数值的扩展:
		ES6 在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法。
		Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity。		Number.isNaN()用来检查一个值是否为NaN。
		Number.parseInt(), Number.parseFloat() 
		Number.isInteger()用来判断一个数值是否为整数。   {还有math对象的扩展}
######函数的扩展:
		ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。function log(x, y = 'World')		参数变量是默认声明的,所以不能用letconst再次声明。
		参数默认值可以与解构赋值的默认值,结合起来使用。function foo({x, y = 5})   foo({x: 1}) // 1 5
		function f(x, y = 5, z)    f(1, undefined, 2) // [1, 5, 2]   默认的需要传入undefined   null不行 
		函数的length属性 => 将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。函数的length属性,不包括 rest 参数。
				(function (a) {}).length // 1
				(function (a = 5) {}).length // 0
				(function (a, b, c = 5) {}).length // 2
		如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。
				(function (a = 0, b, c) {}).length // 0
				(function (a, b = 1, c) {}).length // 1
		利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
		function throwIfMissing() {
			throw new Error('Missing parameter');
		}
		function foo(mustBeProvided = throwIfMissing()) {
			return mustBeProvided;
		}
		foo()				// Error: Missing parameter		

ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,function add(…values)
注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.prototype.slice.call先将其转为数组
严格模式: ‘use strict’;
ES2016 做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
两种方法可以规避这种限制。第一种是设定全局性的严格模式,这是合法的。第二种是把函数包在一个无参数的立即执行函数里面。
函数的name属性,返回该函数的函数名。 Function构造函数返回的函数实例,name属性的值为anonymous。 (bind返回的函数,name属性值会加上bound前缀。)
箭头函数:
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错

Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。
						function* helloWorldGenerator(){
						  yield 'hello';
						  yield 'world';
						  return 'ending';
						}
								hw.next()
						// {value:'hello', done:false}
						hw.next()
						// {value:'world', done:false}
						hw.next()
						// {value:'ending', done:false}
						hw.next()
						// {value:undefined, done:true}
数组的扩展:
		const a1 = [1, 2];			a2[0] = 2;
		const a2 = a1;			a1 // [2, 2];
		上面代码中,a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。
		const a2 = a1.concat();   实际是连接方法 可克隆     ES6可运用扩展运算符来操作   ...
		Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
				// ES5的写法 						可以转换arguments
				var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
				// ES6的写法
				let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
		如果对象不带length属性,那么转出来就是空数组。  必须有length属性  |||	
				console.log('%s', Array.from({
				  0: '0',
				  1: '1',
				  3: '3',
				  length:4
				}))
		Array.from(arrayLike[, mapFn[, thisArg]])			Array.from可以接受三个参数
				arrayLike:被转换的的对象。
				mapFn:map函数。
				thisArg:map函数中this指向的对象。
		Array.of方法用于将一组值,转换为数组。	Array.of(3, 11, 8) // [3,11,8]
		数组实例的copyWithin方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。
		Array.prototype.copyWithin(target, start = 0, end = this.length)		这三个参数都应该是数值,如果不是,会自动转为数值。[1, 2, 3, 4, 5].copyWithin(0, 3)
				target(必需):从该位置开始替换数据。如果为负值,表示倒数。
				start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
				end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
		数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,
		直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined[1, 4, -5, 10].find((n) => n < 0)			// -5
		数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1[1, 5, 10, 15].findIndex(function(value, index, arr) {
				  return value > 9;
				}) // 2
		另外,这两个方法都可以发现NaN,弥补了数组的indexOf方法的不足。
		fill方法使用给定值,填充一个数组   ['a', 'b', 'c'].fill(7)		// [7, 7, 7]
		fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
		
		ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象(详见《Iterator》一章),
		可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
				for (let [index, elem] of ['a', 'b'].entries()) {
				  console.log(index, elem);
				}
				如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历。		
		Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。ES2016 引入了该方法。
				[1, 2, 3].includes(2)     // true   该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置
		另外,Map 和 Set 数据结构有一个has方法,需要注意与includes区分。Map 结构的has方法,是用来查找键名的		Set 结构的has方法,是用来查找值的
		注意,空位不是undefined,一个位置的值等于undefined,依然是有值的。空位是没有任何值,in运算符可以说明这一点。
		ES6 则是明确将空位转为undefinedfor...of循环也会遍历空位。Array.from方法会将数组的空位,转为undefined
		
		Map的回调函数参数依次为value、key和map本身:Set与Array类似,但Set没有索引,因此回调函数的前两个参数都是元素本身:
对象的扩展:
		const foo = 'bar';				defineProperty		getOwnPropertyDescriptor
		const baz = {foo};
		baz // {foo: "bar"}
		Object.is(NaN, NaN) // true		
        //   ES5 比较两个值是否相等,只有两个运算符				不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
		Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
				由于undefinednull无法转成对象,所以如果它们作为参数,就会报错。
		Object.assign方法实行的是浅拷贝,而不是深拷贝。同名属性的替换    Object.assign可以用来处理数组,但是会把数组视为对象。	
		Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制
		对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
		另外,ES6 规定,所有 Class 的原型的方法都是不可枚举的。
		Object.keys(obj);   取所有对象属性集合
		// 子类续承父类
		Rectangle.prototype = Object.create(Shape.prototype);
		Rectangle.prototype.constructor = Rectangle;
		ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for...of循环使用。
				let {keys, values, entries} = Object;
				let obj = { a: 1, b: 2, c: 3 };
				for (let key of keys(obj)) {
				  console.log(key); // 'a', 'b', 'c'
				}
				for (let value of values(obj)) {
				  console.log(value); // 1, 2, 3
				}
				for (let [key, value] of entries(obj)) {
				  console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
				}
        Symbol:
		ES5 的对象属性名都是字符串,这容易造成属性名的冲突。
        比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。
		如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。
		注意,Symbol函数前不能使用new命令,否则会报错。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
		Symbol 值不能与其他类型的值进行运算,会报错。但是,Symbol 值可以显式转为字符串。Symbol 值也可以转为布尔值,但是不能转为数值。   tostring
		由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名
		另一个新的 API,Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。Reflect.ownKeys(obj)
		Symbol.for		Symbol.keyFor
				有时,我们希望重新使用同一个 Symbol 值,Symbol.for方法可以做到这一点。
				比如,如果你调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值。
		Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key。
				let s1 = Symbol.for("foo");
				Symbol.keyFor(s1) // "foo"
				let s2 = Symbol("foo");
				Symbol.keyFor(s2) // undefined
		Singleton 模式指的是调用一个类,任何时候返回的都是同一个实例。
set 和 map数据结构:

Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。下面先介绍四个操作方法。
add(value):添加某个值,返回 Set 结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。ES6 规定 WeakSet 不可遍历。
首先,WeakSet 的成员只能是对象,而不能是其他类型的值。
const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a);
// WeakSet {[1, 2], [3, 4]}

Proxy:元编程 代理 拦截

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
var proxy = new Proxy(target, handler);
Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。
其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。
// js中in操作符 in 操作符用来判断属性是否存在与对象中。
get()
get方法用于拦截某个属性的读取操作,可以接受三个参数,依次为目标对象、属性名和 proxy 实例本身(即this关键字指向的那个对象),其中最后一个参数可选。
set()
set方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。
apply()
apply方法拦截函数的调用、call和apply操作。
apply方法可以接受三个参数,分别是目标对象、目标对象的上下文对象(this)和目标对象的参数数组。
construct()
construct方法用于拦截new命令,下面是拦截对象的写法。construct方法可以接受两个参数。construct方法返回的必须是一个对象,否则会报错。
target: 目标对象
args:构建函数的参数对象

Reflect:
	Reflect对象与Proxy对象大致相同
Promise:异步操作

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大
Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
Promise对象是一个构造函数,用来生成Promise实例。Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

					const someAsyncThing = function() {
					  return new Promise(function(resolve, reject) {
						// 下面一行会报错,因为x没有声明
						resolve(x + 2);
					  });
					};

					someAsyncThing().then(function() {
					  console.log('everything is great');
					});

					setTimeout(() => { console.log(123) }, 2000);
					// Uncaught (in promise) ReferenceError: x is not defined
	上面代码中,someAsyncThing函数产生的 Promise 对象,内部有语法错误。浏览器运行到这一行,会打印出错误提示ReferenceError: x is not defined,但是不会退出进程、终止脚本执行,
	2 秒之后还是会输出123。这就是说,Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。
Iterator 和 for…of 循环:

未叙述

Generator 函数的异步应用:
	异步编程对 JavaScript 语言太重要。Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可
	ES6 诞生以前,异步编程的方法,大概有下面四种。
			回调函数
			事件监听
			发布/订阅
			Promise 对象
async 函数:
	async 函数是什么?一句话,它就是 Generator 函数的语法糖。
		const asyncReadFile = async function () {
		  const f1 = await readFile('/etc/fstab');
		  const f2 = await readFile('/etc/shells');
		  console.log(f1.toString());
		  console.log(f2.toString());
		};
	一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。
	async函数对 Generator 函数的改进,体现在以下四点。
			(1)内置执行器。
			Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。
			(2)更好的语义。
			async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
			(3)更广的适用性。
			co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
			(4)返回值是 Promise。
			async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
			进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。
Class的基本语法:
	ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。											
	注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。				
	构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。
	类的属性名,可以采用表达式。
				let methodName = 'getArea';
				class Square {
				  constructor(length) {
					// ...
				  }
				  [methodName]() {
					// ...
				  }
				}
	严格模式
	类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。
	考虑到未来所有的代码,其实都是运行在模块之中,所以 ES6 实际上把整个语言升级到了严格模式。
	类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。		
	Class 的静态方法
    类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
		class Foo {
            static classMethod() {
            return 'hello';
            }
        }
    Foo.classMethod() // 'hello'
    var foo = new Foo();
    foo.classMethod()
    // TypeError: foo.classMethod is not a function
    class Foo {
      static classMethod() {
        return 'hello';
      }
    }
    class Bar extends Foo {
    }
Bar.classMethod() // 'hello'
上面代码中,父类Foo有一个静态方法,子类Bar可以调用这个方法。	
目前,只有这种写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。
class MyClass {
  myProp = 42;
  constructor() {
    console.log(this.myProp); // 42
  }
}	
Decorator:
类的修饰:许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为。目前,有一个提案将这项功能,引入了 ECMAScript。
需要babel转码支持		
Module 的语法:
严格模式
ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。		
export 命令
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。	
export default 命令
// export-default.js
    export default function () {
      console.log('foo');
    }	
上面代码是一个模块文件export-default.js,它的默认输出是一个函数。
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

// import-default.js
import customName from ‘./export-default’;
customName(); // ‘foo’
上面代码的import命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数名。
需要注意的是,这时import命令后面,不使用大括号。
export default命令用在非匿名函数前,也是可以的。

首先,安装这个转码器。npm install -g es6-module-transpiler
然后,使用compile-modules convert命令,将 ES6 模块文件转码。compile-modules convert -o out.js file1.js

ES6中另外一个好玩的特性就是Spread Operator 也是三个点儿…接下来就展示一下它的用途。
    //数组
    const color = ['red', 'yellow']
    const colorful = [...color, 'green', 'pink']
    console.log(colorful) //[red, yellow, green, pink]
    
    //对象
    const alp = { fist: 'a', second: 'b'}
    const alphabets = { ...alp, third: 'c' }
    console.log(alphabets) //{ "fist": "a", "second": "b", "third": "c"}
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。
//  它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。
//  注:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值