ECMAScript 8都发布了,你用的是什么版本?

2020-07-18 23:17:01 2875

什么是ES6?ES6就是ECMAScript6,是新版本的JavaScript语言标准。其实ECMAScript 6.0早在2015年6月正式发布了,它是新版本的 JavaScript 语言标准,主要是使用JavaScript 语言来为企业级编写复杂的大型应用程序,是一种开发语言。目前大多数环境及框架都支持ES6标准。


ES6和ES5相比,它给开发人员带来了很多新的特性。它的语法相较于其他版本而言会更加的简洁规范,但是在功能上更加强大,可以简单的实现复杂的操作。除此以外,ES6的应用,让前后语法更加统一,差异大大缩小,大大提升开发效率,提高了代码的安全性。

在ES6中以下是一些比较常用的特性,例如:Classes(类)、Modules(模块)、Default Parameters(默认参数)、Arrow Functions (箭头函数)、Multi-line Strings (多行字符串)、Template Literals (模板字符串)、Enhanced Object Literals (增强的对象文本)、Destructuring Assignment (解构赋值)、Block-Scoped Constructs Let and Const(块作用域构造Let and Const)以及Promises等。

以下就是对常用的ES6特性的介绍。

其实在ES6中,需要声明变量的关键字除了var和function还新增加了let、const、class和import。 其中let和const要和块级作用域结合才能发挥其优势。
  那什么是块级作用域?块级作用域的表示任何一对大括号{}包围的语句集都是一个块,而在这个作用域里面定义的所有变量在代码块外都是不可访问的,所以是块级作用域。当然,在块级作用域中还可以声明函数,该函数也是只能作用域内部才能被访问到。块级作用域可以避免内层变量覆盖外层变量可以更好的来管理变量。

  在ES6之前,javascript中没有块级作用域的概念,也就是说,JS并不支持块级作用域,它只支持函数作用域,而且只有全局作用域和函数作用域两种。在javascript使用函数作用域时,就表明变量在声明它们的函数时,所有变量在函数体内始终是可见的,有定义的。这样就意味着变量在声明之前就可以使用,这个特性被称为“声明提前”,即javascript函数里用var或者function声明的所有变量或者函数会被提前到作用域的顶部。

在使用let声明的变量时,只在它所在的块级作用域内有效代码块内有效。 let不允许在相同作用域内,重复声明同一个变量,不能跨块访问,也不能跨函数访问。而var定义的变量,没有块的概念,可以跨块访问 ,且声明会被提前。var命令会发生变量提升现象,也就是说变量可以在声明之前使用。但有一点需要注意,在let声明变量前,使用该变量语句,会报错该变量未被声明。如以下例子在最新版本的Chrome浏览器的控制台(支持一部分ES6语法)执行就会报错。

{

  var hello = 'Hello'

  let world = 'World'

}

console.log(hello);

console.log(world);

let与constconst声明使用基本相同,同样是存在于块级作用域内。最大不同点就是:const声明一个只读的常量。一旦声明,常量的值就不能改变,而且必须同时给常量初始化赋值,不然会报错。

而在ES6中,除了增加了let和const两种声明方式,还有接下来要介绍的import和class的声明方式。

Default Parameters(默认参数)是ES6中对函数拓展的一个特性,可以直接为函数的参数设置默认值,当某一参数设置了默认值时,如果调用函数的时候没有传该参数,则该参数的值为默认值,如果传了该参数,则该参数的值为传递的参数值。

在ES6之前,函数的参数设置默认值都是通过手动的方式设置,代码如下:

function sign (x) {

if (typeof x === 'undefined') {

x = 'default'

}

console.log(x)

}

sign('new sign')    // new sign

sign()              // default

如果将上述代码换成ES6模式,如下:

function sign (x = 'default') {

console.log(x)    

}

sign('new sign')    // new sign

sign()              // default

通过对比可以看出,ES6把默认值部分从大括号移到了小括号里,还减少了运算,这样看上去更加简洁明了。

在ES6中,Enhanced Object Literals (增强的对象文本)对象字面值扩展支持在创建时设置原型,简写foo:foo分配,定义方法是通过加工父函数(super calls),计算属性名(动态)。

var obj = {

// __proto__ 原型

__proto__: theProtoObj,

 // Shorthand for ‘handler: handler’  简写

handler,

// Methods

toString() {

// Super calls     继承

return "d " + super.toString();

},

// Computed (dynamic) property names 计算属性名

['prop_' + (() => 42)()]: 'name'

};

 

在ES6中Template Literals (模板字符串)是使用反引号 (` `) 和${  }来代替普通字符串中的用双引号和单引号,实现字符串的拼接,字符串中可以嵌入变量。

但是在ES6之前,我们的输出代码一般是:

var name = 'Henry'

var welcome = 'Hello, ' + name + '!'

console.log(welcome);   // Hello, Henry!

在ES6中,模板字符串可以这样拼接字符串:let name = 'Henry'

let welcome = `Hello, ${ name }!`;

console.log(welcome);   // Hello, Henry

模板字符串的计算原则是在两个反引号之间将字符串拼接到一起,如果反引号之间含有${  },则会计算这对大括号内的值,大括号里面可以是任意的JavaScript表达式,可以进行运算和引用对象属性。代码如下:

let a = 3;

let number = `$ {a + 2 }`;

console.log(`${ number }`);    // 5

let b = { c: 2, d: 4 };

console.log(`${ b.c * b.d }`) ;     // 8

Multi-line Strings (多行字符串)跟Template Literals (模板字符串)是同样的解析方式,它是模板字符串的拓展,但是它可以拼接多行的字符串,且拼接的字符串中会保留所有的空格和缩进。

如果需要用字符串来拼接DOM树结构时,可以这样写:

let titleValue = 'This is a title';

let htmlStr = `

可以从以上代码看出它们是JavaScript和伪html代码的结合,它可以将模板字符串的多行字符串封装成一个页面模板工具。这种书写方式跟JSX非常相似。

在ES6中是允许使用“箭头”( => )定义函数,称作Arrow Functions (箭头函数)。(=> 前面的部分是函数的参数,=> 后面的部分是函数的代码块。)

在ES5中声明一个函数,代码如下:

var func = function (a) {

return a + 2;

}

但是若将这个函数换成箭头函数,代码如下:

let func = a => a + 2;

如果箭头函数有多个参数,需要用括号将它们括起来,只有一个参数的时候,可以省略括号,如果没有设置参数,也必须有括号。示代码如下:

let func1 = (arg1, arg2, arg3) => {

return arg1 + arg2 + arg3;

}

let func2 = arg => {

console.log(arg)

}

let func3 = () => {

console.log(`This is an arrow function.`)

}

需要注意的是,箭头函数内部没有自己的this,如果在箭头函数内部使用this,那样这个this是箭头函数外部的this,也是因为箭头函数没有this,这样就会导致内部的this 就是外层代码块的 this。所以,箭头函数不能用作构造函数。如果用箭头函数来写回调函数时,就不用再将外部this保存起来了。

箭头函数的代码如下:

// ES6

function foo() {

setTimeout(() => {

console.log(`id:${ this.id }`)        

}, 100)

}

// ES5

function foo() {

var _this = this;

setTimeout(function() {

console.log('id:', _this.id);        

}, 100)

}

Promise是异步编程的一种解决方案,它是一个对象,它的状态不受外界影响且只要开始就会一直进行下去,直到成功或者失败,也可以从它可以获取异步操作的消息。就像一个容器一样,一旦状态改变就不会再变,任何时候都是这种结果。

Promise的结果是由异步操作的结果决定的,且一旦结果形成,便不可再被改变,任何时候都得到同样的结果。但需要注意的是Promise对象中的状态一旦被确定为成功或者失败,无法被取消,会执行下去,直到出现结果,如果不设置回调,那内部抛出的异常,是不会被反应到外部的。