• ES6新特性概览


    ES6新特性概览

    来源 http://www.cnblogs.com/Wayou/p/es6_new_features.html

    本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用。

    ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony(和谐之意,显然没有跟上我国的步伐,我们已经进入中国梦版本了)。上一次标准的制订还是2009年出台的ES5。目前ES6的标准化工作正在进行中,预计会在14年12月份放出正式敲定的版本。但大部分标准已经就绪,且各浏览器对ES6的支持也正在实现中。要查看ES6的支持情况请点此

    目前想要运行ES6代码的话,可以用google/traceur-compiler将代码转译。点此访问traceur-compiler 在线版本时实编辑ES6代码并查看转换后的结果,代码运行结果会在console显示。

    另外,关于Google Traceur,业界大神Addy Osmani利用前者写了个Chrome插件ES6 Tepl,安装后也可以进行ES6的测试。

    当然,并不是所有ES6新特性都被实现了,所以上面的方法可以测试大部分,有一些还是无法测试的。

    虽然ES6都还没真正发布,但已经有用ES6重写的程序了,各种关于ES789的提议已经开始了,这你敢信。潮流不是我等大众所能追赶的。

    潮流虽然太快,但我们不停下学习的步伐,就不会被潮流丢下的,下面来领略下ES6中新特性,一堵新生代JS的风采。

    箭头操作符

    如果你会C#或者Java,你肯定知道lambda表达式,ES6中新增的箭头操作符=>便有异曲同工之妙。它简化了函数的书写。操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs。

    我们知道在JS中回调是经常的事,而一般回调又以匿名函数的形式出现,每次都需要写一个function,甚是繁琐。当引入箭头操作符后可以方便地写回调了。请看下面的例子。

    var array = [1, 2, 3];
    //传统写法
    array.forEach(function(v, i, a) {
        console.log(v);
    });
    //ES6
    array.forEach(v = > console.log(v));
    

    大家可以打开文章开头提到的traceur在线代码转译页面输入代码来查看效果。

    类的支持

    ES6中添加了对类的支持,引入了class关键字(其实class在JavaScript中一直是保留字,目的就是考虑到可能在以后的新版本中会用到,现在终于派上用场了)。JS本身就是面向对象的,ES6中提供的类实际上只是JS原型模式的包装。现在提供原生的class支持后,对象的创建,继承更加直观了,并且父类方法的调用,实例化,静态方法和构造函数等概念都更加形象化。

    下面代码展示了类在ES6中的使用。再次啰嗦一句,你可以将代码贴到traceur自己查看运行结果。

    //类的定义
    class Animal {
    	//ES6中新型构造器
        constructor(name) {
            this.name = name;
        }
        //实例方法
        sayName() {
            console.log('My name is '+this.name);
        }
    }
    //类的继承
    class Programmer extends Animal {
        constructor(name) {
        	//直接调用父类构造器进行初始化
            super(name);
        }
        program() {
            console.log("I'm coding...");
        }
    }
    //测试我们的类
    var animal=new Animal('dummy'),
    wayou=new Programmer('wayou');
    animal.sayName();//输出 ‘My name is dummy’
    wayou.sayName();//输出 ‘My name is wayou’
    wayou.program();//输出 ‘I'm coding...’
    

    增强的对象字面量

    对象字面量被增强了,写法更加简洁与灵活,同时在定义对象的时候能够做的事情更多了。具体表现在:

    • 可以在对象字面量里面定义原型
    • 定义方法可以不用function关键字
    • 直接调用父类方法

    这样一来,对象字面量与前面提到的类概念更加吻合,在编写面向对象的JavaScript时更加轻松方便了。

    //通过对象字面量创建对象
    var human = {
        breathe() {
            console.log('breathing...');
        }
    };
    var worker = {
        __proto__: human, //设置此对象的原型为human,相当于继承human
        company: 'freelancer',
        work() {
            console.log('working...');
        }
    };
    human.breathe();//输出 ‘breathing...’
    //调用继承来的breathe方法
    worker.breathe();//输出 ‘breathing...’
    

    字符串模板

    字符串模板相对简单易懂些。ES6中允许使用反引号 ` 来创建字符串,此种方法创建的字符串里面可以包含由美元符号加花括号包裹的变量${vraible}。如果你使用过像C#等后端强类型语言的话,对此功能应该不会陌生。

    //产生一个随机数
    var num=Math.random();
    //将这个数字输出到console
    console.log(`your num is ${num}`);
    

    解构

    自动解析数组或对象中的值。比如若一个函数要返回多个值,常规的做法是返回一个对象,将每个值做为这个对象的属性返回。但在ES6中,利用解构这一特性,可以直接返回一个数组,然后数组中的值会自动被解析到对应接收该值的变量中。

    var [x,y]=getVal(),//函数返回值的解构
        [name,,age]=['wayou','male','secrect'];//数组解构
    
    function getVal() {
        return [ 1, 2 ];
    }
    
    console.log('x:'+x+', y:'+y);//输出:x:1, y:2 
    console.log('name:'+name+', age:'+age);//输出: name:wayou, age:secrect 
    

    参数默认值,不定参数,拓展参数

    默认参数值

    现在可以在定义函数的时候指定参数的默认值了,而不用像以前那样通过逻辑或操作符来达到目的了。

    function sayHello(name){
    	//传统的指定默认参数的方式
    	var name=name||'dude';
    	console.log('Hello '+name);
    }
    //运用ES6的默认参数
    function sayHello2(name='dude'){
    	console.log(`Hello ${name}`);
    }
    sayHello();//输出:Hello dude
    sayHello('Wayou');//输出:Hello Wayou
    sayHello2();//输出:Hello dude
    sayHello2('Wayou');//输出:Hello Wayou
    

    不定参数

    不定参数是在函数中使用命名参数同时接收不定数量的未命名参数。这只是一种语法糖,在以前的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
    }

    注意,此功能google traceur并未实现,所以无法模拟调试,下面有些功能也是如此

    iterator, generator

    这一部分的内容有点生涩,详情可以参见这里。以下是些基本概念。

    • iterator:它是这么一个对象,拥有一个next方法,这个方法返回一个对象{done,value},这个对象包含两个属性,一个布尔类型的done和包含任意值的value
    • iterable: 这是这么一个对象,拥有一个obj[@@iterator]方法,这个方法返回一个iterator
    • generator: 它是一种特殊的iterator。反的next方法可以接收一个参数并且返回值取决与它的构造函数(generator function)。generator同时拥有一个throw方法
    • generator 函数: 即generator的构造函数。此函数内可以使用yield关键字。在yield出现的地方可以通过generator的next或throw方法向外界传递值。generator 函数是通过function*来声明的
    • yield 关键字:它可以暂停函数的执行,随后可以再进进入函数继续执行

    模块

    在ES6标准中,JavaScript原生支持module了。这种将JS代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如CommonJS和AMD模式。

    将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。下面的例子来自tutsplus:

    // 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 方法。

    下方代码来自es6feature

    // Sets
    var s = new Set();
    s.add("hello").add("goodbye").add("hello");
    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则更加安全些,这些作为属性键的对象如果没有别的变量在引用它们,则会被回收释放掉,具体还看下面的例子。

    正文代码来自es6feature

    // 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
    

    上面代码我已加了注释,这里进一步解释。对于处理程序,是在被侦听的对象身上发生了相应事件之后,处理程序里面的方法就会被调用,上面例子中我们设置了set的处理函数,表明,如果我们侦听的对象的属性被更改,也就是被set了,那这个处理程序就会被调用,同时通过参数能够得知是哪个属性被更改,更改为了什么值。

    Symbols

    我们知道对象其实是键值对的集合,而键通常来说是字符串。而现在除了字符串外,我们还可以用symbol这种值来做为对象的键。Symbol是一种基本类型,像数字,字符串还有布尔一样,它不是一个对象。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的。之后就可以用这个返回值做为对象的键了。Symbol还可以用来创建私有属性,外部无法直接访问由symbol做为键的属性值。

    以下例子来自es6features

    (function() {
    
      // 创建symbol
      var key = Symbol("key");
    
      function MyClass(privateData) {
        this[key] = privateData;
      }
    
      MyClass.prototype = {
        doStuff: function() {
          ... this[key] ...
        }
      };
    
    })();
    
    var c = new MyClass("hello")
    c["key"] === undefined//无法访问该属性,因为是私有的
    

    Math,Number,String,Object 的新API

    对Math,Number,String还有Object等添加了许多新的API。下面代码同样来自es6features,对这些新API进行了简单展示。

    Number.EPSILON
    Number.isInteger(Infinity) // false
    Number.isNaN("NaN") // false
    
    Math.acosh(3) // 1.762747174039086
    Math.hypot(3, 4) // 5
    Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
    
    "abcde".contains("cd") // true
    "abc".repeat(3) // "abcabcabc"
    
    Array.from(document.querySelectorAll('*')) // Returns a real Array
    Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
    [0, 0, 0].fill(7, 1) // [0,7,7]
    [1,2,3].findIndex(x => x == 2) // 1
    ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
    ["a", "b", "c"].keys() // iterator 0, 1, 2
    ["a", "b", "c"].values() // iterator "a", "b", "c"
    
    Object.assign(Point, { origin: new Point(0,0) })
    

    Promises

    Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式。

    //创建promise
    var promise = new Promise(function(resolve, reject) {
        // 进行一些异步或耗时操作
        if ( /*如果成功 */ ) {
            resolve("Stuff worked!");
        } else {
            reject(Error("It broke"));
        }
    });
    //绑定处理程序
    promise.then(function(result) {
    	//promise成功的话会执行这里
        console.log(result); // "Stuff worked!"
    }, function(err) {
    	//promise失败会执行这里
        console.log(err); // Error: "It broke"
    });
    

    总结

    总结就是一句话,前后端差异越来越小了。

    REFERENCE

    ECMAScript 6 学习笔记

    作用域不同

    • ES6中,let和const实际上为JavaScript新增了块级作用域,函数本身的作用域,在其所在的块级作用域之内。
    • let和const的用法

      相同点:(1)用来声明变量 (2) 声明的变量只在它所在的代码块有效 (3) 不像var那样,会发生“变量提升”现象,只要块级作用域内存在let或const命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。 (4)不允许在相同作用域内,重复声明同一个变量

    不同点:const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变。let声明的变量可以改变。

    • 全局对象。 ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令、const命令、class命令声明的全局变量,不属于全局对象的属性,无法通过window/global获取。

    变量的解构赋值

    • 定义:ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

      eg: var [a, b, c] = [1, 2, 3]; 相当于 var a = 1;var b = 2;var c = 3;

    • 解构只能用于数组或对象,其他原始类型的值都可以转为相应的对象。
    • 解构赋值允许指定默认值。

      eg :[x, y='b'] = ['a'] // x='a', y='b'

    • 对象解构可以与函数参数的默认值一起使用。

      eg :function move({x=0, y=0} = {}) { return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, 0] move({}); // [0, 0] move(); // [0, 0]

    • 用途:(1)交换变量的值 (2) 从函数返回多个值 (3) 函数参数的定义 (4) 提取JSON数据 (5) 函数参数的默认值 (6) 遍历Map结构 (7) 输入模块的指定方法

    字符串的扩展

    • 新增加codePointAt()、String.fromCodePoint()、at()处理需要4个字节储存的字符(Unicode码点大于0xFFFF的字符)
    • ES6对正则表达式添加了u修饰符,用来正确处理大于uFFFF的Unicode字符;
      • (1) 点(.)字符在正则表达式中,对于码点大于0xFFFF的Unicode字符,点字符不能识别,必须加上u修饰符。
      • (2) Unicode字符表示法:ES6新增了使用大括号表示Unicode字符,这种表示法在正则表达式中必须加上u修饰符,才能识别。
      • (3) 使用u修饰符后,所有量词都会正确识别大于码点大于0xFFFF的Unicode字符。
      • (4) u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的Unicode字符。
      • (5) i修饰符/[a-z]/i.test('u212A') // false /[a-z]/iu.test('u212A') // true 上面代码中,不加u修饰符,就无法识别非规范的K字符。
    • ES6又提供了三种新方法,用来确定一个字符串是否包含在另一个字符串中。

      includes():返回布尔值,表示是否找到了参数字符串。 startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。 endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。

    • 正则表达式的y修饰符:它的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始,不同之处在于,g修饰符只确保剩余位置中存在匹配,而y修饰符确保匹配必须从剩余的第一个位置开始
    • 模板字符串:用反引号( ` )标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。如果在模板字符串中嵌入变量,需要将变量名写在${}之中。

      注意:(1)如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。 (2) 大括号内部可以进行运算,以及引用对象属性。 (3)模板字符串之中还能调用函数 (4) 如果模板字符串中的变量没有声明,将报错。

    • String.raw方法,往往用来充当模板字符串的处理函数,返回字符串被转义前的原始格式。

      eg :String.raw({ raw: 'test' }, 0, 1, 2);// 't0e1s2t'
      等同于String.raw({ raw: ['t','e','s','t'] }, 0, 1, 2);

      数值的扩展

    • ES6提供了二进制和八进制数值的新的写法,分别用前缀0b和0o表示

      eg: 0b111110111 === 503 // true
      0o767 === 503 // true

    • ES6在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法,用来检查Infinite和NaN这两个特殊值。 它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,非数值一律返回false。
    • ES6将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。
    • Number.isInteger()用来判断一个值是否为整数;
    • (1)Math.trunc方法用于去除一个数的小数部分,返回整数部分
      (2)Math.sign方法用来判断一个数到底是正数、负数、还是零。如果参数为正数,返回+1;参数为负数,返回-1;参数为0,返回0;参数为NaN,返回NaN。
    • ES6在Math对象上还提供了许多新的数学方法。包括Math.acosh(x)、Math.asinh(x)等

    数组的扩展

    • (1) Array.from()用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象,其中包括ES6新增的Set和Map结构。
      (2) Array.of()方法用于将一组值,转换为数组。
    • (1) 数组实例的find()用于找出第一个符合条件的数组元素。它的参数是一个回调函数,所有数组元素依次遍历该回调函数,直到找出第一个返回值为true的元素,然后返回该元素,否则返回undefined。
      (2)数组实例的findIndex()的用法与find()非常类似,返回第一个符合条件的数组元素的位置,如果所有元素都不符合条件,则返回-1。
    • fill()使用给定值,填充一个数组
    • ES6提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
    • ES7新增 includes() 方法返回一个布尔值,表示某个数组是否包含给定的值
    • ES6提供简洁写法,允许直接通过现有数组生成新数组,这被称为数组推导
    • Array.observe(),Array.unobserve() 这两个方法用于监听(取消监听)数组的变化,指定回调函数。数组可监听的变化一共有四种:add、update、delete、splice(数组的length属性发生变化)。

    对象的扩展

    • 属性的简洁表示法
    • 属性名表达式 obj['a'+'bc'] = 123;
    • Object.is()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
    • Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。
    • ES6引入了一种新的原始数据类型Symbol,表示独一无二的ID。它通过Symbol函数生成。

      a) Symbol.for方法在全局环境中搜索指定key的Symbol值,如果存在就返回这个Symbol值,否则就新建一个指定key的Symbol值并返回。
      b) Symbol.keyFor方法返回一个已登记的Symbol类型值的key。

    • ES6新增加Proxy用于修改某些操作的默认行为
    • (1)Object.observe方法用来监听对象(以及数组)的变化。一旦监听对象发生变化,就会触发回调函数。 Object.observe方法目前共支持监听六种变化。

    add:添加属性
    update:属性值的变化
    delete:删除属性
    setPrototype:设置原型
    reconfigure:属性的attributes对象发生变化
    preventExtensions:对象被禁止扩展(当一个对象变得不可扩展时,也就不必再监听了)

    (2) Object.unobserve方法用来取消监听。

    函数的扩展

    • ES6允许为函数的参数设置默认值 。 注意定义了默认值的参数,必须是函数的尾部参数,其后不能再有其他无默认值的参数。指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。
    • ES6引入rest参数(...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。 注意,rest参数之后不能再有其他参数,否则会报错。
    • 扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。该运算符主要用于函数调用。
    • ES6允许使用“箭头”(=>)定义函数。

      eg:var f = v => v;

    箭头函数有几个使用注意点:
    (1) 函数体内的this对象,绑定定义时所在的对象,而不是使用时所在的对象。
    (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。 (3)不可以使用arguments对象,该对象在函数体内不存在。

    Set和Map数据结构

    • ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

      a) Set结构有以下属性:(1)Set.prototype.constructor:构造函数,默认就是Set函数。 (2)Set.prototype.size:返回Set的成员总数。
      b) Set数据结构有以下方法:(1) add(value):添加某个值,返回Set结构本身。 (2) delete(value):删除某个值,返回一个布尔值,表示删除是否成功。 (3) has(value):返回一个布尔值,表示该值是否为Set的成员。 (4) clear():清除所有成员,没有返回值
      c) Array.from方法可以将Set结构转为数组。
      d) 支持数组遍历方式。

    • WeakSet结构与Set类似,也是不重复的值的集合。但是,它与Set有两个区别。 首先,WeakSet的成员只能是对象,而不能是其他类型的值。其次,WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,因此WeakSet是不可遍历的。
    • ES6提供了map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应。

    a) Map数据结构有以下属性和方法:

    (1)size:返回成员总数。
    (2)set(key, value):设置key所对应的键值,然后返回整个Map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
    (3)get(key):读取key对应的键值,如果找不到key,返回undefined。
    (4)has(key):返回一个布尔值,表示某个键是否在Map数据结构中。
    (5)delete(key):删除某个键,返回true。如果删除失败,返回false。
    (6)clear():清除所有成员,没有返回值。

    b) Map原生提供三个遍历器:keys(),values(),entries()

    • WeakMap结构与Map结构基本类似,唯一的区别是它只接受对象作为键名(null除外),不接受原始类型的值作为键名,而且键名所指向的对象,不计入垃圾回收机制。

    Iterator(遍历器)

    • 在ES6中具备Iterator接口:数组、某些类似数组的对象、Set和Map结构。
    • ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性。也就是说,调用Symbol.iterator方法,就会得到当前数据结构的默认遍历器。Symbol.iterator是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为Symbol的特殊值,所以要放在方括号内
    • 调用默认iterator接口的场合:
      (1) 解构赋值:对数组和Set结构进行解构赋值时,会默认调用iterator接口。
      (2) 扩展运算符
    • ES6中,一个数据结构只要部署了Symbol.iterator方法,就被视为具有iterator接口,就可以用for...of循环遍历它的成员。

    Generator 函数

    • ES6引入Generator函数,作用就是可以完全控制函数的内部状态的变化,依次遍历这些状态。Generator是一个普通函数,但是有两个特征。一是,function命令与函数名之间有一个星号;二是,函数体内部使用yield语句,定义遍历器的每个成员,即不同的内部状态
    • next方法的参数
      next方法可以带一个参数,该参数就会被当作上一个yield语句的返回值。
    • for...of循环可以自动遍历Generator函数,且此时不再需要调用next方法。
    • Generator函数还有一个特点,它可以在函数体外抛出错误,然后在函数体内捕获。
    • yield*语句:如果yield命令后面跟的是一个遍历器,需要在yield命令后面加上星号,表明它返回的是一个遍历器。

    Promise对象

    • Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象还提供了一整套完整的接口,使得可以更加容易地控制异步操作。
    • Promise.prototype.then方法返回的是一个新的Promise对象,因此可以采用链式写法。
    • Promise.prototype.catch方法是Promise.prototype.then(null, rejection)的别名,用于指定发生错误时的回调函数。
    • Promise.all()、Promise.race()方法用于将多个Promise实例,包装成一个新的Promise实例。
    • Promise.resolve()、Promise.reject(),将现有对象转为Promise对象
    • 使用Generator函数管理流程,遇到异步操作的时候,通常返回一个Promise对象。

    Class

    • a) ES6引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
      b) constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,该方法会被默认添加
      c) 生成实例对象的写法,与ES5完全一样,也是使用new命令。如果忘记加上new,像函数那样调用Class,将会报错。

      d) 可以通过proto属性为Class添加方法。
      e) ES6的Class只是ES5的构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性。
      f) 与函数一样,Class也可以使用表达式的形式定义。
      g) Class不存在变量提升
      h) 类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。

    • Class的继承:Class之间可以通过extends关键字,实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
      注意子类必须在constructor方法中调用super方法,否则新建实例时会报错。
    • class的取值函数(getter)和存值函数(setter):在Class内部可以使用get和set关键字,对某个属性设置存值函数和取值函数。


    本文是学习ES6的一点心得,想要具体学习ES6,请参考阮老师的书,电子版地址点这里

  • 相关阅读:
    第二章:列表简介
    第三章:shell变量知识进阶
    第二章:shell变量
    WEB服务器
    第一章:变量和简单的数据类型
    第一节:python基础
    第一章:shell脚本初入门
    vim命令
    知识点一:OSI模型初识
    知识点二:HTTP超文本文件传输协议
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7760354.html
Copyright © 2020-2023  润新知