我相信,在ECMAScript.next到来的时候,我们现在每天都在写的JavaScript代码将会发生巨大的变化.接下来的一年将会是令JavaScript开发者们兴奋的一年,越来越多的特性提案将被最终敲定,新一版本的JavaScript将会慢慢得到普及.

本文中,我将会讲几个我个人很期待的,希望能在2013年或者更晚一点使用上的新特性.

ES.next目前的实现情况

可以通过查看Juriy Zaytsev总结的ECMAScript 6兼容性表格,和Mozilla的ES6实现情况页面以及通过使用现代浏览器的最新版本(比如Chrome CanaryFirefox Aurora),来了解目前有哪些已经实现了的ES.next特性.

在Canary中,记得要进入启用实验性JavaScript'选项以激活所有最新的的JavaScript特性.

另外,许多ES.next特性还可以通过使用Google的Traceur转换编译器(这里有一些单元测试的例子)来体验,以及一些shim项目比如ES6-ShimHarmony Collections,也实现了不少新特性.

在Node.js(V8)中使用 模块

我们已经习惯了将我们的代码分割成为更加便于管理的功能块.在ES.next中,一个模块(module)是就是一个

  1.     
  2.     
  3. }  

一个模块实例就是一个被求过值的模块,它已经被链接到了其他的模块身上或者已经有了词法上的封装数据.下面是一个模块实例的例子:

  1. ;
  1. module Universe { module MilkyWay {} };  
  2. module MilkyWay = ;  
  3. module SolarSystem = Universe.MilkyWay.SolarSystem;  
  4. module MySystem = SolarSystem;  

一个

  1.      var;  
  2.      exportfunction     console.log(, speed, direction);  
  3.   }  
  4.   export     exportfunction   }  
  5.   exportvar   exportvar;  
  6. };  

一个模块可以使用drive() 再次用到上面导出相关的例子,我们现在可以有选择性的导入一些模块中的功能.

比如我们可以导入

  1. import drive from Car;  

还可以可以同时导入miles:

  1. import {drive, miles} from Car;

下面,我们要讲一下模块加载器API的概念.模块加载器能够让我们动态的加载所需要的脚本.类似于export声明过的东西.

  1. Loader.load(, function   console.log(car.drive(500, ));
  2. }, function   console.log( + err);
  3. });
  • 关于类(class)

    我不打算在本文中过多的讲ES.next中的,如果你想知道类和模块将会有什么联系,Alex Russell曾经写过一个很好的例子来说明这件事.

    JavaScript中有了类,并不意味着要把JavaScript变成Java.ES.next中的类只是我们已经熟悉的语义(比如函数,原型)的另外一种声明方式

    下面是用来定义一个widget的ES.next代码:

    1. classextends     constructor(attributes) {
    2. super       this     }
    3. buildUI() {
    4. thisfunction
    5. };
    6. }
    7. }
    8. }

    下面是去糖(de-sugared)后的做法,也就是我们目前正在使用的方法:

    1. varfunction
    2. function     Widget.call(this     this   }
    3. DropDownButton.prototype = Object.create(Widget.prototype, {
    4. constructor: { value: DropDownButton },
    5. buildUI:     {
    6. value: function         thisfunction
    7. }
    8. }
    9. }
    10. });
    11. })(this);

    ES.next的写法的确让代码变的更可读.这里的function,至少是做了目前我们用 这些模块如何和AMD配合使用?

    ES.next中的模块是朝着正确的方向走了一步吗?也许是吧.我自己的看法是:看相关的规范文档是一码事,实际上使用起来又是另一码事.在Harmonizr,Require HMTraceur中可以体验新的模块语法,你会非常容易的熟悉这些语法,该语法可能会觉得有点像Python的感觉(比如 我认为,如果一些功能有足够广泛的使用需求(比如模块),那么平台(也就是浏览器)就应该原生支持它们.而且,并不是只有我一个人这么觉得. James Burke,发明了AMD和RequireJS的人,也曾经说过:

    我想,AMD和 RequireJS应该被淘汰了.它们的确解决了一个实际存在的问题,但更理想的情况是,语言和运行环境应该内置类似的功能.模块的原生支持应该能够覆盖 RequireJS 80%的使用需求,从这一点上说,我们不再需要使用任何用户态(userland)的模块加载库了,至少在浏览器中是这样.

    不过James的质疑是ES.next的模块是否是一个足够好的解决方案,他曾在六月份谈到过自己关于ES.next中模块的一些想法 ES6 Modules: Suggestions for improvement以及再后来的一篇文章Why not AMD?.

    Isaac Schlueter前段时间也写过一些自己的想法,讲到了ES6的模块有哪些不足.尝试一下下面这些选项,看看你的想法如何.

    兼容目前引擎的Module实现

    Object.observe()

    通过 属性观察是我们经常会在MVC框架中看到的行为,它是数据绑定的一个重要组件,AngularJS和Ember.js都有自己的解决方案.

    这是一个非常重要的新功能,它不仅比目前所有框架的同类实现性能要好,而且还能更容易的观察纯原生对象.

    1. var
          label: ,
    2. completed: false
      };
    3. Object.observe(todoModel, function
          changes.forEach(function
              console.log(change);
    4. });
    5. });
    6. todoModel.label = ;
    7. todoModel.completeBy = ;
    8. delete

    Object.observe马上将会在Chrome Canary中实现(需要开启"启用实验性JavaScript"选项).

    兼容目前引擎的Object.observe()实现

    • Chromium特殊版本
    • Watch.JS 可以实现类似的功能,但它并不是实现
      Rick Waldron的这篇文章有关于

      译者注:Firefox很早就有了一个类似的东西:Object.prototype.watch.

      默认参数值

      默认参数值(Default
      parameter values)的作用是:在一些形参没有被显式传值的情况下,使用默认的初始化值来进行初始化.这就意味着我们不再需要写类似options = options || {};这样的语句了.

      该语法形式就是把一个初始值赋值给对应的形参名:

      1. function) {
      2. console.log(caption);
      3. }
      4. addTodo();

      拥有默认参数值的形参只能放在形参列表的最右边:

      1. function
        function, order = 4) {}
      2. functionthis) {}

      已经实现该特性的浏览器: Firefox 18+

      译者注:Firefox 15就已经实现了默认参数值,作者所说的18只是说18支持,并不是说18是第一个支持的版本.包括本文下面将要提到的chrome 24+等等,都有这个问题.

      块级作用域

      块级作用域引入了两种新的声明形式,可以用它们定义一个只存在于某个语句块中的变量或常量.这两种新的声明关键字为:

      • var, 但定义的变量只存在于当前的语句块中
      • let类似,但声明的是一个只读的常量

      使用var可以更容易的定义一个只在某个语句块中存在的局部变量,而不用担心它和函数体中其他部分的同名变量有冲突.在var声明的变量和在var声明的变量没什么差别,它们都拥有函数作用域,而不是块级作用域.

      译者注:以防读者看不懂,我用一个例子解释一下上面的这句话,是这样的:

      let(var1 = 1) {
      alert(var1); //弹出1,var1是个块级作用域变量
      var var2 = 2;
      }
      var var3 = 3;
      alert(var2); //弹出2,虽然var2是在let语句内部声明的,但它仍然是个函数作用域内的变量,因为使用的是var声明
      alert(var3); //弹出3
      alert(var1); //抛出异常
      1. var var let (x = x+10, y = 12) {
      2. console.log(x+y);
      3. }
      4. console.log(x + y);

      实现 实现const的浏览器: Firefox 18+, Chrome 24+,  Safari 6+, WebKit, Opera 12+

      译者注:Firefox很久以前就支持了letconst,但这两个旧的实现都是依据了当年的ES4草案.和目前的ES6草案有些区别,比如ES4中用const声明的常量并没有块级作用域(和var一样,只是值不可变),let也有一些细微差别,就不说了.由于很少人使用旧版的Firefox(但我的主浏览器是FF3.6!),即使未来ES6和ES4中的一些东西有冲突,我们基本也可以忽略.

      Map

      我想大部分读者已经熟悉了映射的概念,因为我们过去一直都是用纯对象来实现映射的.Map允许我们将一个值映射到一个唯一的键上,然后我们就可以通过这个键获取到对应的值,而不需要担心用普通对象实现映射时因原型继承而带来的问题.

      使用get()方法,可以获取到所存储的值.Map对象还有其他三个方法:

      • size() : 返回map中键值对的个数
      1. new m.set(, .length);   m.get();
      2. m.has();
      3. m.delete'todo'
      4. m.has();

      已经实现Map的浏览器: Firefox 18+

      Nicholas Zakas的这篇文章有关于Map更详细的介绍.

      兼容目前引擎的Map实现

      译者注:我翻译过尼古拉斯的这篇文章:[译]ECMAScript 6中的集合类型,第二部分:Map.

      作者可能不知道,10月份的ES6草案中,Set.prototype.size都从size()方法改成size访问器属性了.同时Map对象新添加的方法还有很多,clear()用来清空一个map,forEach()用来遍历一个map,还有items(),keys(),values()等.Set对象也类似,有不少作者没提到的方法,下面的Set小节我就不指出了.

      另外,在ES5中,在把对象当成映射来使用的时候,为了防止原型继承带来的问题(比如在twitter中,@__proto__能让浏览器卡死),可以用var hash = Object.create(null)代替var hash = {};

      Set

      正如Nicholas Zakas在他的文章中所说,对于那些接触过Ruby和Python等其他语言的程序员来说,Set并不是什么新东西,但它的确是在JavaScript中一直都缺少的特性.

      任何类型的数据都可以存储在一个set中,但每个值只能存储一次(不能重复).利用Set可以很方便的创建一个不包含任何重复值的有序列表.

      • has(value) – 返回一个布尔值,表明value这个值是否存在于这个set中.
      1. new// s有1, 2, 3三个元素. s.has(-Infinity);
      2. s.add(-Infinity);            // s有1, 2, 3, -Infinity四个元素. s.has(-Infinity);
      3. s.delete
      4. s.has(-Infinity);

      Set对象的一个作用是用来降低过滤操作(filter方法)的复杂度.比如:

      1. function     varnew     returnfunction         if             seen.add(item);
      2. returntrue         }
      3. });
      4. }

      这个利用Set来进行数组去重的函数的复杂度为O(n).而其他现有数组去重方法的复杂度几乎都为O(n^2).

      已经实现Set的浏览器: Firefox 18, Chrome 24+.

      Nicholas Zakas的这篇文章有关于Set更详细的介绍.

      兼容目前引擎的Set实现

      译者注:我翻译过尼古拉斯的这篇文章:[译]ECMAScript 6中的集合类型,第一部分:Set.

      如果让我来实现一个ES6下的数组去重函数的话,我会这么写:

      function unique(array) {   
      return [v for(v of Set(array))]
      }

      该函数使用到了ES6中的for-of遍历,以及数组推导式.不过效率比上面使用filter去重的方法稍微差点.Firefox最新版中已经可以执行这个函数.

      另外,借助于下面将会提到的Array.from方法,还有更简单高效的写法:

      >Array.from(new Set([ 1, 1, 2, 2, 3, 4 ]));
      [1,2,3,4]

      甚至,借助于ES6中的展开(spread)操作,还有可能这样实现:

      >[ ... new Set([ 1, 1, 2, 2, 3, 4 ]) ];
      [1,2,3,4]

      WeakMap

      WeakMap的键只能是个对象值,而且该键持有了所引用对象的弱引用,以防止内存泄漏的问题.这就意味着,如果一个对象除了WeakMap的键以外没有任何其他的引用存在的话,垃圾回收器就会销毁这个对象.

      WeakMap的另外一个特点是我们不能遍历它的键,而Map可以.

      1. new m.set(, .length);
      2. m.has();
      3. let wmk = {};
      4. m.set(wmk, );
      5. m.get(wmk);
      6. m.has(wmk);
      7. m.delete
      8. m.has(wmk);

      已经实现WeakMap的浏览器: Firefox 18+, Chrome 24+.

      兼容目前引擎的WeakMap实现

      Nicholas Zakas的这篇文章有关于WeakMap更详细的介绍.

      译者注:我翻译过尼古拉斯的这篇文章:[译]ECMAScript 6中的集合类型,第三部分:WeakMap

      代理

      代理(Proxy)API允许你创建一个属性值在运行期间动态计算的对象.还可以利用代理API"钩入"其他的对象,实现例如打印记录和赋值审核的功能.

      1. var};
      2. var   get: function     return+ propertyName;
      3. }
      4. });
      5. console.log(proxyObj.Alex);

      可以看看Nicholas Zakas的这篇文章这个例子.

      实现代理API的浏览器: Firefox 18+, Chrome 24+

      译者注:作者不知道的是,一共有过两个代理API的提案,一个是旧的Catch-all Proxies,一个是新的直接代理(Direct Proxies).前者已被废弃.两者的区别在这里.V8(Chrome和Node.js)实现的是前者,Firefox18及之后版本实现的是后者(17及之前版本实现的是前者).尼古拉斯在2011年写的文章也应该是过时的.

      一些新的API

      Object.is

      ===最主要的区别是在对待特殊值Object.is的判断结果是:NaN是相等的,以及+0和-0是不等的.

      1. Object.is(NaN, NaN);
      2. 0 === -0;
      3. NaN === NaN;

      实现了Object.is的浏览器: Chrome 24+

      兼容目前引擎的Object.is实现

      译者注:Object.is方法和严格相等===运算符的区别体现在ES标准内部就是SameValue算法严格相等比较算法的区别.

      译者注:如果我没有理解错这条BE的推特的话,Object.is要改名成为Object.sameValue了.

      Array.from

      1.     0: ,  
      2.     1: ,  
      3.     2: ,  
      4.     length: 3  
      5. });  

      再比如转换一个DOM节点集合:

      1. var);
      2. Array.from(divs);
      3. Array.from(divs).forEach(function     console.log(node);
      4. });

      兼容目前引擎的Array.from实现

      译者注:从作者举的两个例子可以看出,Array.from基本相当于目前使用的[].prototype.slice.call.

      目前的草案也的确是这样规定的,但从Rick Waldron(TC39成员)在原文评论中给出的代码可以看出,也许Array.from未来也能将Set对象(非类数组对象,但可迭代)转换成数组.

      译者注:除了这两个API,还有很多个新添加的API,比如

      Number.isFiniteisNaNisIntegertoInteger

      String.prototype.repeatstartsWith, endsWith, contains, toArray

      下面给出两个很有用的链接:

      Mozilla正计划实现的ES6特性https://wiki.mozilla.org/ES6_plans.

      ES6目前的所有特性提案http://wiki.ecmascript.org/doku.php?id=harmony:proposals

      总结

      ES.next中添加了许多被认为是JavaScript中缺失已久的新特性.虽然ES6规范计划在2013年年底发布,不过浏览器们已经开始实现其中的一些特性了,这些特性被广泛使用也只是时间问题了.

      在ES6完全实现之前,我们可以使用一些转换编译器(transpiler)或者shim来体验其中一些特性.

      译者注:目前最强大的ES6实现应该是Brandon Benvie写的continuum,这是一个JavaScript虚拟机,也就是用JavaScript(ES3)实现的JavaScript(ES6)引擎,它未来甚至可以工作在IE6上.目前实现的ES6特性有:模块以及模块加载器API,直接代理,生成器,解构,@symbols(我翻译成标志,这是一个不可能通过shim方式实现的语法)等等.

      想要查看更多的例子和了解最新的信息,可以去TC39
      Codex Wiki
      ,该站点由Dave Herman和其他一些EC39成员维护(译者注:该新站仍在建设中,应该访问旧站).其中包含了下一代JavaScript中将要有的所有新特性.

      激动人心的时刻马上就要到来了!


ES6:JavaScript 新特性的更多相关文章

  1. ES6常用新特性

    https://segmentfault.com/a/1190000011976770?share_user=1030000010776722 该文章为转载文章!仅个人喜好收藏文章! 1.前言 前几天 ...

  2. ES6 && ECMAScript2015 新特性

      ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES201 ...

  3. ES6相关新特性介绍

    你可能已经听说过 ECMAScript 6 (简称 ES6)了.ES6 是 Javascript 的下一个版本,它有很多很棒的新特性.这些特性复杂程度各不相同,但对于简单的脚本和复杂的应用都很有用.在 ...

  4. es6的新特性--模板字符串

    这几天简单看了一下深入浅出es6这本书,感觉特实用,学习了一个新特性---模板字符串在项目开发中,拼接字符串是不可缺少的,动态创建dom元素以及js操作数据都要拼接字符串,在es6出来之前,我们都通常 ...

  5. JS - ECMAScript2015(ES6)新特性

    友情提示:本文仅mark几个常用的新特性,详细请参见:ES6入门 - ryf: 碎片 var VS let VS const var:声明全局变量, let:声明块级变量,即局部变量 const:声明 ...

  6. ES6的新特性(1)——ES6 的概述

    ES6 的概述 首先,感谢马伦老师的ES6新特性的教程. ECMAScript 和 JavaScript 的关系是 ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前 ...

  7. H5、C3、ES6的新特性

    H5的新特性 1.语义化标签 有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重. 语义化的HTML在没有CSS的情况下也能呈现较好的内容结构与代码结构 方便其 ...

  8. ES6实用新特性

    兼容性 http://kangax.github.io/compat-table/es5/ http://kangax.github.io/compat-table/es6/ ES6(ES2015)兼 ...

  9. javascript新特性

    让我们看看javascript中的一些新特性.本文将介绍它们的语法和相关链接,以帮助读者及时了解它们的进展.我们将通过编写一个小测试项目来演示如何快速使用这些新功能! 关于提案 提案分为五个阶段.有关 ...

随机推荐

  1. 10.关联(Association)

    关联关系是类与类之间最常用的一种关系,它是一种结构化关系,用于表示一类对象与另一类对象之间有联系.它体现的是两个类.或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友.这种关系比依赖更强.不存 ...

  2. spring AOP Bean添加新方法

    目的:为studentAdditionalDetails中添加Student的showDetails()和ExtraShowDetails()两个方法 spring  中AOP能够为现有的方法添加额外 ...

  3. css去掉a标签点击后的虚线框(转自网络)

    outline是css3的一个属性,用的很少. 声明,这是个不能兼容的css属性,在ie6.ie7.遨游浏览器都不兼容. outline控制的到底是什么呢? 当聚焦a标签的时候,在a标签的区域周围会有 ...

  4. SAE J1850 VPW PWM, SAE J2411 SWC, ISO 11898 CAN, SAE J1708, Chrysler CCD 接口芯片电路

    SAE J1850 VPW 接口芯片电路 SAE J1850 PWM 接口芯片电路 SAE J2411 SWC 接口芯片电路 ISO 11898 CAN 接口芯片电路 CANH 和CANL 上的电容 ...

  5. ghostDoct 使用 (转 http://www.cnblogs.com/RockyMyx/archive/2010/04/20/Project-Route-Using-GhostDoc.html)

    一.简介 GhostDoc是Visual Studio的一个免费插件,可以为开发人员自动生成XML格式的注释文档. 二.下载 需要的朋友可以去这里下载,填个Email地址就可以下了:GhostDoc下 ...

  6. 战舰少女 黑暗炼钢 按键精灵 代码及apk下载

    注: 该代码仅仅适用于1920*1080分辨率的android手机,因为我只有这个分辨率的手机TnT 代码其实蛮简单的,都是比较简单的模拟就好了…… 要改也比较轻松吧 APK下载地址:链接: http ...

  7. SharedObject使用:在FluorineFx.net与Flex中使用共享对象维护在线用户列表实例【转】

    一.添加一个新的FluorineFx的服务类项目OnLineService,删除原有的Sample.cs,并添加一个用户类定义与一个ApplicationAdpater类:如下: /*-- User. ...

  8. 深入学习PHP内核

    http://www.php-internals.com/  深入学习PHP内核 http://www.php-internals.com/book/ http://www.kancloud.cn/@ ...

  9. NServiceBus

    官方网站:http://docs.particular.net/nservicebus/      NServiceBus 是一个用于构建企业级 .NET系统的开源通讯框架.它在消息发布/订阅支持.工 ...

  10. mongodb目录

    1. mongodb 数据库操作--备份 还原 导出 导入 2. ubuntu下mongodb启动脚本 3. mongodb实现远程连接 4. 用java在客户端读取mongodb中的数据并发送至服务 ...