ECMAScript 5和ECMAScript6的新特性以及浏览器支持情况

ECMAScript简介:

它是一种由Ecma国际(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范,javascript在它基础上经行了自己的封装。但通常来说,术语ECMAScript和javascript指的是同一个。业界所说的ECMAScript其实是指一种规范,或者说是一个标准。具体点来说,它其实就是一份文档

JS包含三个部分:ECMAScript(核心)DOM(文档对象模型)BOM(浏览器对象模型),ECMAScript是js语言的基础。

(1) ECMAScript3新增了对正则表达式新控制语句try-catch异常处理的支持,修改了字符处理、错误定义和数值输出等内容。标志着ECMAScript成为了一门真正的编程语言。

(2) 第四版于2008年7月发布前被废弃。

(3)ECMAScript5力求澄清第3版中的歧义,并添加了新的功能。新功能包括:原生JSON对象、继承的方法、高级属性的定义以及引入严格模式

(4) ECMAScript6是继ES5之后的一次主要改进,增添了许多必要的特性,例如:模块和类以及一些实用特性,Maps、Sets、Promises、生成器(Generators)等。

历史

1998年6月,ECMAScript 2.0版发布。
1999年12月,ECMAScript 3.0版发布,成为JavaScript的通行标准,得到了广泛支持。
2007年10月,ECMAScript 4.0版草案发布,对3.0版做了大幅升级,预计次年8月发布正式版本。草案发布后,由于4.0版的目标过于激进,各方对于是否通过这个标准,发生了严重分歧。以Yahoo、Microsoft、Google为首的大公司,反对JavaScript的大幅升级,主张小幅改动;以JavaScript创造者Brendan Eich为首的Mozilla公司,则坚持当前的草案。
2008年7月,由于对于下一个版本应该包括哪些功能,各方分歧太大,争论过于激进,ECMA开会决定,中止ECMAScript 4.0的开发,将其中涉及现有功能改善的一小部分,发布为ECMAScript 3.1,而将其他激进的设想扩大范围,放入以后的版本,由于会议的气氛,该版本的项目代号起名为Harmony(和谐)。会后不久,ECMAScript 3.1就改名为ECMAScript 5。
2009年12月,ECMAScript 5.0版正式发布。Harmony项目则一分为二,一些较为可行的设想定名为JavaScript.next继续开发,后来演变成ECMAScript 6;一些不是很成熟的设想,则被视为JavaScript.next.next,在更远的将来再考虑推出。
2011年6月,ECMAscript 5.1版发布,并且成为ISO国际标准(ISO/IEC 16262:2011)。
2013年3月,ECMAScript 6草案冻结,不再添加新功能。新的功能设想将被放到ECMAScript 7。
2013年12月,ECMAScript 6草案发布。然后是12个月的讨论期,听取各方反馈。
2015年6月17日,ECMAScript 6发布正式版本,即ECMAScript 2015
ECMA的第39号技术专家委员会(Technical Committee 39,简称TC39)负责制订ECMAScript标准,成员包括Microsoft、Mozilla、Google等大公司。TC39的总体考虑是,ES5与ES3基本保持兼容,较大的语法修正和新功能加入,将由JavaScript.next完成。

浏览器支持

一般来说,除了针对个别特性的特殊说明,各大主流浏览器都支持es5,包括

  • Chrome 13+
  • Firefox 4+
  • Safari 5.1*
  • IE 9*

其中IE9不支持es的严格模式,从IE10开始支持。Safari 5.1不支持 Function.prototype.bind

IE8只支持definePropertygetOwnPropertyDescriptor的部分特性和JSon的新特性,IE9支持除了严格模式以外的新特性,IE10和其他主流浏览器都支持了。
因此在PC端开发的时候,要注意IE9以下的兼容,移动端开发时,可以比较放心了

Strict Mode,即所谓的严格模式。在严格模式下,我们不可以使用一个未经声明的变量以前没有用var声明的变量,会自动成为全局变量,而在严格模式下,会报错。例:

"use strict"
function foo() {
var testVar = 4;
return testVar;
}
// This causes a syntax error.
testVar = 5; //全局变量
开启严格模式的方法很简单,只需要在文件的顶部写上字符串 use strict 即可。当然这需要执行环境支持严格模式。另外由于 use strict 其实是一个字符串常量。那么即使遇到不支持严格模式的环境,
这行字符串只会被安全的忽略,不会带来任何的问题。

JSON对象

JSON.parse(jsonstr); //可以将json字符串转换成json对象 
JSON.stringify(jsonobj); //可以将json对象转换成json对符串

ES5提供一个内置的(全局)JSON对象,可用来序列化( JSON.stringfy )反序列化( parse )对象为JSON格式。其一般性用法如下,

var test = {
"name": "gejiawen",
"age": 22
};
console.log(JSON.strinfy(test)); // '{"name": "gejiawen", "age": 22}'
console.log(JSON.parse('{"name": "larry"}')); // Object {name: "larry"}

JSON对象提供的 parse 方法还提供第二个参数,用于对具体的反序列化操作做处理。比如,

JSON.parse('{"name": "gejiawen", "age": 22, "lucky": "13"}', function(key, value) {
return typeof value === 'string' ? parseInt(value) : value;
});

这里我们在回调函数中对解析的每一对键值对作处理,如果其是一个数字字符串,我们则对其进行 parseInt 操作,确保返回的 value 必定是数值型的。

JSON对象提供的 stringify 方法也会提供第二个参数,用于解析的预处理,同时也会提供第三个参数,用于格式化json字符串。比如,

var o = {
name: 'gejiawen',
age: 22,
lucky: '13'
};
var ret = JSON.stringify(o, function(key, value) {
return typeof value === 'string' ? undefined : value;
}, 4);
console.log(ret);

上面代码在输出时,得到的字符串将不会再呈现一行输出,而是正常的格式化输出,并采用4个space进行格式化。

另外,如果预处理函数的返回值为 undefined ,则此键值对将不会包含在最终的JSON字符串中。所以上面代码最终的结果是,

"{
"age": 22
}"
新增 Object 接口比较常用的有如下几个,
  • Object.create
  • Object.defineProperties
  • Object.keys

新增 Array 接口

对象构造器说明
Array.prototype indexOf 返回根据给定元素找到的第一个索引值,否则返回-1
Array.prototype lastIndexOf 方法返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1
Array.prototype every 测试数组的所有元素是否都通过了指定函数的测试
Array.prototype some 测试数组中的某些元素是否通过了指定函数的测试
Array.prototype forEach 让数组的每一项都执行一次给定的函数
Array.prototype map 返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组
Array.prototype filter 利用所有通过指定函数测试的元素创建一个新的数组,并返回
Array.prototype reduce 接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终为一个值
Array.prototype reduceRight 接受一个函数作为累加器,让每个值(从右到左,亦即从尾到头)缩减为一个值

新增的数组接口中,基本都是比较有用的接口。需要注意的一点是,有的数组方法是不返回新数组的,有的接口是返回一个新数组,就是说使用这些新接口时,需要注意一下方法的返回值。还有一个 Array.isArray(),用来判断某一对象是否为数组。(typeof判断的话,返回object,用instanceof判断的话,IE上的返回值不正确)

Function.prototype.bind

bind()方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

此方法的用法如下,

fun.bind(thisArg[, arg1[, arg2[, ...]]])

使用 bind 可以为函数自定义 this 指针。它的常见使用场景如下,

this.x = 9; 
var module = {
x: 81,
getX: function() {
return this.x;
}
};
module.getX(); // 81
var getX = module.getX;
getX(); // 9, 因为在这个例子中,"this"指向全局对象
// 创建一个'this'绑定到module的函数
var boundGetX = getX.bind(module);
boundGetX(); // 81

Javascript中重新绑定 this 变量的语法还有 call 和 apply 。不过 bind 显然与它们有着明显的不同。 bind 将会返回一个新的函数,而 call 或者 apply 并不会返回一个新的函数,它们将会使用新的 this 指针直接进行函数调用。

ES6的新特性(http://www.cnblogs.com/Wayou/p/es6_new_features.html)

(1)箭头操作符=>:操作符左边为输入的参数,而右边则是进行的操作以及返回的值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));

(2)类的支持--class关键字:JS本身就是面向对象的,ES6中提供的类实际上只是JS原型模式的包装。现在提供原生的class支持后,对象的创建,继承更加直观了,并且父类方法的调用,实例化,静态方法和构造函数等概念都更加形象化。

//类的定义
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...’

(3)增强的对象字面量:

具体表现在:

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

(4)字符串模板:ES6中允许使用反引号 ` 来创建字符串,此种方法创建的字符串里面可以包含由美元符号加花括号包裹的变量${vraible}。

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

(5)解构
(6)参数默认值,不定参数,拓展参数
(7)let与const 关键字:可以把let看成var,它定义的变量被限定在了特定范围内才能使用,而离开这个范围则无效。const则很直观,用来定义常量,即无法被更改值的变量。

for (let i=0;i<2;i++)console.log(i);//输出: 0,1 console.log(i);//输出:undefined,严格模式下会报错
(8)for of 值遍历:for in 循环用于遍历数组,类数组或对象,ES6中新引入的for of循环功能相似,不同的是每次循环它提供的不是序号而是值。

var someArray = [ "a", "b", "c" ];
 
for (v of someArray) {
    console.log(v);//输出 a,b,c
}

(9)iterator, generator
(10)模块
(11)Proxies
(12)Symbols
(13)Math,Number,String,Object 的新API
(14)Promises

ES6的浏览器支持情况

链接:http://www.xuebuyuan.com/2122607.html
基本上是没有浏览器完全支持的,所以还是不要直接用的好。
但是有转换器 (更准确地说是源代码到源代码的编译器) 可以把ES6转换为被浏览器接受的ES5,比如Babel以及Traceur 之类的项目。其中Babel对 ES6 的支持程度比其它同类更高,而且 Babel 拥有完善的文档和一个很棒的在线交互式编程环境,因此用的比较多。

REFERENCE

原文地址:https://www.cnblogs.com/Anderson-An/p/10018043.html