我相信,在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. css去掉a标签点击后的虚线框(转自网络)

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

  2. C++的优秀特性6:智能指针

    (转载请注明原创于潘多拉盒子) 智能指针(Smart Pointer)是C++非常重要的特性.考虑如下一段使用简单指针(Plain Pointer)的代码: A* a = new A(); B* b ...

  3. 数据结构复习:交换排序原理及C++实现

    1. 交换排序的基本思想 两两比较key值,如果发生逆序(排列的顺序与期望的顺序相反)就交换,知道所有对象都排序完毕!常见的3种交换排序算法:冒泡排序,shaker排序和快速排序. 2. 冒泡排序 设 ...

  4. Response.Redirect 打开新窗体的两种方法

    普通情况下,Response.Redirect 方法是在server端进行转向,因此,除非使用 Response.Write("<script>window.location=' ...

  5. 解决黑苹果与windows时区不一致

    原理就是将windows识别硬件时间为UTC-0而不是现在的UTC+8 下面都是抄来的 注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\T ...

  6. javascript 操作 excel 全攻略

    最近做一个项目,用到了javascript操纵excel以生成报表,下面是标有详细注解的实例 <html> <head><script language="ja ...

  7. 制作Windows的ico图标

    也不知道这个方法是不是最好的,有时间再查看其它方法 首先设计出图标,png格式即可. 使用一款软件 IconWorkshop 下载了一个试用版,临时制作够用了 制作步骤如下: 1.打开png图片 2. ...

  8. C#封装、多态、抽象、接口、匿名方法等学习

    1:封装 将对象进行封装,并不等于将整个对象完全包裹起来,而是根据实际需要,设置一定的访问权限,用户根据不同的权限调用对象提供的功能,在C#语言中,可以使用修饰符public.internal.pro ...

  9. 利用FluorineFx的ByteArray上传图片

    Flex端利用new PNGEncoder().encode(bitmapData)将png图片转换为ByteArray,然后传给服务器,服务端需要定义一个public ByteArray Uploa ...

  10. 关于Android圆形图片的一种优化方案(可以显示网络图片)

    在Android App中,我们经常看到圆形头像图片,然后网上也有很多开源的控件.刚好这个项目用到了,也去找了一些开源的,发现并不完美,所以只好自己优化了,废话不多说,先上效果图: 下面是源码:本人能 ...