JavaScript ES6功能概述(ECMAScript 6和ES2015 +)

JavaScript在过去几年中发生了很大的变化。这些是您今天可以开始使用的12项新功能!

该语言的新增内容称为ECMAScript 6.它也称为ES6或ES2015 +。

自1995年JavaScript构思以来,它一直在缓慢发展。每隔几年就会发生新增事件。 ECMAScript于1997年成立,旨在指导JavaScript的发展方向。它已经发布了ES3,ES5,ES6等版本。

如您所见,ES3,ES5和ES6之间存在10年和6年的差距。此后每年??进行小幅增量变更。而不是像ES6那样一次做大规模的改变。

所有现代浏览器和环境都支持ES6!

Chrome,MS Edge,Firefox,Safari,Node等等都支持 JavaScript ES6大多数功能 。因此,您将在本教程中学习的所有内容都可以立即开始使用。

让我们开始使用ECMAScript 6!

您可以在浏览器控制台上测试所有这些代码段!

块级作用域

使用ES6,我们从使用var声明变量到使用let / const。

var出了什么问题?

var的问题是变量泄漏到其他代码块中,例如for循环或if块。


ES5
var x = ‘outer‘;
function test(inner) {
  if (inner) {
    var x = ‘inner‘;// scope whole function
        return x;
  }
      return x;// gets redefined because line 4 declaration is hoisted
    }
    test(false);// undefined ??
    test(true);// inner

对于test(false)你会期望返回outer,但是你却得到undefined。

为什么?

因为即使没有执行if-block,第4行中的表达式“var x”也会被提升。

var是函数作用域。它甚至在被声明之前就可以在整个功能中使用。

声明已被挂载。因此,您可以在声明变量之前使用它。

初始化不会被提升。如果您使用var ,那么总会将变量声明在顶部。

在应用挂载规则后,我们可以更好地了解发生的情况:


ES5
var x = ‘outer‘;
function test(inner) {
  var x;// HOISTED DECLARATION
  if (inner) {
    x = ‘inner‘;// INITIALIZATION NOT HOISTED
    return x;
  }
  return x;
}

ES6
let x = ‘outer‘;
function test(inner) {
  if (inner) {
      let x = ‘inner‘;
    return x;
  }
      return x;// gets result from line 1 as expected
}
test(false);// outer
test(true);// inner

用let代替var会使事情按预期工作。如果未调用if块,则变量x不会从块中提升。

hoisting和 “temporal dead zone”

在ES6中,let将变量提升到块的顶部(不是像ES5那样位于函数的顶部)。

但是,在变量声明之前引用块中的变量会导致“ReferenceError(系统报错)”。

let被限制为块级作用域。在声明之前不能使用它。

“Temporal dead zone” 是从块开始到声明变量的区域。

让我们在解释IIFE之前展示一个例子。 看看这里:


ES5
{
  var private = 1;
}
console.log(private);// 1

如你所见,private漏掉了。 您需要使用IIFE(立即调用的函数表达式)来包含它:


ES5
(function(){
  var private2 = 1;})();
console.log(private2);// Uncaught ReferenceError

如果你看过jQuery / lodash或其他开源项目,你会发现他们有IIFE来避免污染全局环境,只是在全局定义,如_,$或jQuery。

在ES6上更清洁,当我们只使用块和let时,我们也不需要再使用IIFE:


ES6
{
  let private3 = 1;
}
console.log(private3);// Uncaught ReferenceError

如果你根本不想改变变量,你也可以使用const。

用‘let和const代替var`。

对所有引用使用const;避免使用var。

如果必须重新分配引用,请使用let而不是const。

模板文字(字符串拼接)
当我们有模板文字时,我们不需要做更多的嵌套连接。看一看:


ES5
var first = ‘Adrian‘;
var last = ‘Mejia‘;
console.log(‘Your name is ‘ + first + ‘ ‘ + last + ‘.‘);```
现在你可以使用backtick()和字符串插值$ {}:

const first = ‘Adrian‘;
const last = ‘Mejia‘;
console.log(Your name is ${first} ${last}.);`

多行字符串

我们不必再连接字符串+ n了:


var template = ‘<li *ngFor="let todo of todos" [ngClass]="{completed: todo.isDone}" >\n‘ +
‘  <div class="view">\n‘ +
‘    <input class="toggle" type="checkbox" [checked]="todo.isDone">\n‘ +
‘    <label></label>\n‘ +
‘    <button class="destroy"></button>\n‘ +
‘  </div>\n‘ +
‘  <input class="edit" value="">\n‘ +
‘</li>‘;
console.log(template);

在ES6上我们可以再次使用反引号来解决这个问题:


const template = `<li *ngFor="let todo of todos" [ngClass]="{completed: todo.isDone}" >
  <div class="view">
    <input class="toggle" type="checkbox" [checked]="todo.isDone">
    <label></label>
    <button class="destroy"></button>
  </div>
  <input class="edit" value="">
</li>`;
console.log(template);

两段代码都会有完全相同的结果。

解构分配

ES6解构非常有用和简洁。请遵循以下示例:

从数组中获取元素


ES5
var array = [1, 2, 3, 4];
var first = array[0];
var third = array[2];
console.log(first, third);// 1 3

es6的写法:


ES6
const array = [1, 2, 3, 4];
const [first, ,third] = array;
console.log(first, third);// 1 3

交换 values


ES5
var a = 1;
var b = 2;
var tmp = a;
a = b;
b = tmp;
console.log(a, b);// 2 1```
es6的写法:

ES6
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b);// 2 1



### 多次返回值的解构

ES5
function margin() {
var left=1, right=2, top=3, bottom=4;
return {


  left: left, right: right, top: top, bottom: bottom };

}
var data = margin();
var left = data.left;
var bottom = data.bottom;
console.log(left, bottom);// 1 4`
在第3行中,您还可以将其返回到这样的数组中(并保存一些输入):

return [left, right, top, bottom];
但是,调用者需要考虑返回数据的顺序。


var left = data[0];
var bottom = data[3];

使用ES6,调用者只选择他们需要的数据(第6行):


ES6
function margin() {
  const left=1, right=2, top=3, bottom=4;
  return { left, right, top, bottom };
}
const { left, bottom } = margin();
console.log(left, bottom);// 1 4

注意:第3行,我们还有其他一些ES6功能正在进行中。我们可以将{left:left}压缩为{left}。看看它与ES5版本相比有多简洁。那不是很酷吗?

参数匹配的解构


ES5
var user = {
  firstName: ‘Adrian‘, lastName: ‘Mejia‘
};
function getFullName(user) {
  var firstName = user.firstName;
  var lastName = user.lastName;
  return firstName + ‘ ‘ + lastName;
}
console.log(getFullName(user));// Adrian Mejia

es6(但更简洁)相同:


ES6
const user = {
  firstName: ‘Adrian‘, lastName: ‘Mejia‘
};
function getFullName({
  firstName, lastName
}) {  return ${firstName} ${lastName};}
console.log(getFullName(user));// Adrian Mejia

深拷贝


ES5
function settings() {
  return { display: { color: ‘red‘ }, keyboard: { layout: ‘querty‘} };}
var tmp = settings();
var displayColor = tmp.display.color;var keyboardLayout = tmp.keyboard.layout;
console.log(displayColor, keyboardLayout);// red querty

与es6(但更简洁)相同:


ES6
function settings() {
  return { display: { color: ‘red‘ }, keyboard: { layout: ‘querty‘} };
}
const {
  display: { color: displayColor }, keyboard: { layout: keyboardLayout }
} = settings();
console.log(displayColor, keyboardLayout);// red querty

这也称为对象解构。

如您所见,这非常有用,并鼓励良好的编码风格。

最佳做法:

  • 使用数组解构来获取元素或交换变量。它可以帮助您避免创建临时引用。
  • 不要对多个返回值使用数组解构,而是使用对象解构

类和对象

使用ECMAScript 6,我们从“构造函数”went到“类”went。

在JavaScript中,每个对象都有一个原型,这是另一个对象。所有JavaScript对象都从其原型继承其方法和属性。

在ES5中,我们使用构造函数来创建面向对象编程(OOP),以创建对象,如下所示:


ES5
var Animal = (function () {
  function MyConstructor(name) {    this.name = name;
}
MyConstructor.prototype.speak = function speak() {    console.log(this.name + ‘ makes a noise.‘);
};
return MyConstructor;})();
var animal = new Animal(‘animal‘);
animal.speak();// animal makes a noise.

在ES6中,我们有一些语法糖。我们可以用更少的样板和新的关键字来做同样的事情,比如class和constructor。另外,请注意我们如何定义方法


constructor.prototype.speak = function()vsspeed():

ES6
class Animal {
  constructor(name) {    this.name = name;}
    speak() {    console.log(this.name + ‘ makes a noise.‘);
 }
}
const animal = new Animal(‘animal‘);
animal.speak();// animal makes a noise.

正如我们所看到的,两种风格(ES5 / 6)在幕后产生相同的结果,并以相同的方式使用。

最佳做法:

  • 始终使用class语法并避免直接操作prototype。为什么?因为它使代码更简洁,更容易理解。
  • 避免使用空构造函数。如果未指定,则类具有默认构造函数。

继承

建立在之前的Animal类上。假设我们想要扩展它并定义一个“Lion”类

在ES5中,它更多地涉及原型继承。


ES5
var Lion = (function () {
  function MyConstructor(name){
      Animal.call(this, name);
}
// prototypal inheritance
MyConstructor.prototype = Object.create(Animal.prototype);
MyConstructor.prototype.constructor = Animal;
MyConstructor.prototype.speak = function speak() {
  Animal.prototype.speak.call(this);
  console.log(this.name + ‘ roars ??‘);
};
return MyConstructor;})();
var lion = new Lion(‘Simba‘);lion.speak();// Simba makes a noise.
// Simba roars.

我不会详细介绍所有细节,但请注意:

  • 第3行,我们用参数显式调用Animal构造函数。
  • 第7-8行,我们将Lion原型分配给Animal的原型。
  • 第11行,我们从父类Animal中调用speak方法。

在ES6中,我们有一个新的关键字extends和super![superman shield](undefined)。


class Lion extends Animal {
  speak() {    super.speak();
  console.log(this.name + ‘ roars ??‘);
}}
const lion = new Lion(‘Simba‘);
lion.speak();// Simba makes a noise.
// Simba roars.

看起来这个ES6代码与ES5相比看起来有多清晰,它们完全相同。

最佳做法:

使用内置的方式继承extends。

Promises

我们从回调地狱??逃出来了。


ES5
function printAfterTimeout(string, timeout, done){
  setTimeout(function(){
      done(string);
}, timeout);}
printAfterTimeout(‘Hello ‘, 2e3, function(result){
  console.log(result);// nested callback
  printAfterTimeout(result + ‘Reader‘, 2e3, function(result){
    console.log(result);
 });
});

我们有一个函数接收回调,当done时执行。我们必须一个接一个地执行它。这就是我们在回调中第二次调用‘printAfterTimeout`的原因。

如果您需要第3次或第4次回调,这可能会很快变得混乱。让我们看看我们如何通过Promises来做到这一点:


ES6
function printAfterTimeout(string, timeout){
  return new Promise((resolve, reject) => {
      setTimeout(function(){      resolve(string);
}, timeout);
});}
printAfterTimeout(‘Hello ‘, 2e3).then((result) => {
  console.log(result);
  return printAfterTimeout(result + ‘Reader‘, 2e3);
}).then((result) => {
  console.log(result);
});

正如你所看到的,使用promises,我们可以使用then在另一个函数完成后执行某些操作。 不再需要保持嵌套功能。

箭头函数

ES6没有删除函数表达式,但它添加了一个名为箭头函数的新表达式。

在ES5中,我们对this有一些疑问:


ES5
var _this = this;// need to hold a reference
$(‘.btn‘).click(function(event){
  _this.sendData();// reference outer this
});
$(‘.input‘).on(‘change‘,function(event){
  this.sendData();// reference outer this
}.bind(this));// bind to outer this

你需要使用一个临时的this来引用一个函数或使用bind。在ES6中,您可以使用箭头函数来实现这个功能!


ES6
// this will reference the outer one
$(‘.btn‘).click((event) =>  this.sendData());
// implicit returns
const ids = [291, 288, 984];
const messages = ids.map(value => `ID is ${value}`);

For…of

我们从for转到forEach然后转到for ... of:


ES5
// for
var array = [‘a‘, ‘b‘, ‘c‘, ‘d‘];
for (var i = 0;i < array.length;i++) {
  var element = array[i];
  console.log(element);}// forEach
array.forEach(function (element) {  console.log(element);});

ES6 for ...也允许我们进行迭代。


ES6
// for ...of
const array = [‘a‘, ‘b‘, ‘c‘, ‘d‘];
for (const element of array) {
 console.log(element);
}

默认参数

我们检查是否定义了变量以将值赋给“默认参数”。你之前做过这样的事吗?


ES5
function point(x, y, isFlag){
  x = x || 0;
  y = y || -1;
  isFlag = isFlag || true;
  console.log(x,y, isFlag);
}
point(0, 0) // 0 -1 true ??
point(0, 0, false) // 0 -1 true ????
point(1) // 1 -1 true
point() // 0 -1 true

检查的常见模式是变量具有值或指定默认值。然而,请注意有一些问题:

第8行,我们传递0,0并得到‘0,-1`

第9行,我们传递false但得到‘true`。

如果您将布尔值作为默认参数或将值设置为零,则它不起作用。你知道为什么吗???我会在ES6例子后告诉你;)

使用ES6,现在您可以用更少的代码做得更好!


ES6
function point(x = 0, y = -1, isFlag = true){
  console.log(x,y, isFlag);
}
point(0, 0) // 0 0 true
point(0, 0, false) // 0 0 false
point(1) // 1 -1 true
point() // 0 -1 true

注意第5行和第6行我们得到了预期的结果。ES5示例不起作用。我们必须首先检查undefined,因为false,null,undefined和0是假值。我们可以逃脱数字:


ES5
function point(x, y, isFlag){
  x = x || 0;
  y = typeof(y) === ‘undefined‘ ? -1 : y;
  isFlag = typeof(isFlag) === ‘undefined‘ ? true : isFlag;
  console.log(x,y, isFlag);
}
point(0, 0) // 0 0 true
point(0, 0, false) // 0 0 false
point(1) // 1 -1 true
point() // 0 -1 true

现在,当我们检查undefined时,它按预期工作。

Rest parameters

我们从参数到休息参数和传播运算符。

在ES5上,获取任意数量的参数是成熟的:


ES5
function printf(format) {
  var params = [].slice.call(arguments, 1);
  console.log(‘params: ‘, params);
  console.log(‘format: ‘, format);
}

我们可以使用rest运算符...来做同样的事情。


ES6
function printf(format, ...params) {
  console.log(‘params: ‘, params);
  console.log(‘format: ‘, format);
}

扩展运算符

我们从apply()转到了扩展运算符。

提醒:我们使用apply()将数组转换为参数列表。例如,Math.max()接受一个参数列表,但是如果我们有一个数组,我们可以使用apply来使它工作。

正如我们在前面所看到的,我们可以使用apply来传递数组作为参数列表:


ES5
Math.max.apply(Math, [2,100,1,6,43]) // 100

在ES6中,您可以使用扩展运算符:


ES6
Math.max(...[2,100,1,6,43]) // 100

另外,我们从concat数组开始使用spread运算符:


ES5
var array1 = [2,100,1,6,43];
var array2 = [‘a‘, ‘b‘, ‘c‘, ‘d‘];
var array3 = [false, true, null, undefined];
console.log(array1.concat(array2, array3));

在ES6中,您可以使用spread运算符展平嵌套数组:


ES6
const array1 = [2,100,1,6,43];
const array2 = [‘a‘, ‘b‘, ‘c‘, ‘d‘];
const array3 = [false, true, null, undefined];
console.log([...array1, ...array2, ...array3]);

JavaScript经历了很多变化。本文介绍了每个JavaScript开发人员应该了解的大多数核心功能。此外,我们还介绍了一些最佳实践,以使您的代码更简洁,更容易推理。

原文地址:https://www.cnblogs.com/lalalagq/p/9749755.html

时间: 2024-10-04 18:08:09

JavaScript ES6功能概述(ECMAScript 6和ES2015 +)的相关文章

Javascript ES6 特性概述(即ECMAScript 6和ES2015+)

Javascript在过去的一年里变化了很多,从现在开始,有12个新的特性可以开始用了! 1. 历史 ECMAScript 6是对Javascript语言的增强,有时候也被称为ES6或者ES2015+. Javascript诞生在1995年,从那以后一直在缓慢地演变,每隔几年会有一些新的增强特性出现.ECMAScript出现在1997年,目的是指导Javascript的演化路径,它已经发布了好几个版本,如ES3.ES5.ES6,等等. 可以看到,在ES3.ES5和ES6之间分别有10年和6年的空

JavaScript ES6 核心功能一览

JavaScript 在过去几年里发生了很大的变化.这里介绍 12 个你马上就能用的新功能. JavaScript 历史 新的语言规范被称作 ECMAScript 6.也称为 ES6 或 ES2015+ . 自从 1995 年 JavaScript 诞生以来,它一直在缓慢地发展.每隔几年就会增加一些新内容.1997 年,ECMAScript 成为 JavaScript 语言实现的规范.它已经有了好几个版本,比如 ES3 , ES5 , ES6 等等. 如你所见,ES3,ES5 和 ES6 之间分

JavaScript大杂烩13 - 总结ECMAScript 5新功能

虽说这个标准已经出来很久了,所有的主流浏览器的最新版本也都支持了这些特性,但是很多的教程中并没有包含这个部分,这一节我们专门来总结一下这个标准中的新功能. Object的新方法 在最新的JavaScript规范(ECMAScript 5)中,Object扩展了很多不错的静态方法,下面来简单看一下: 1. create/getPrototypeOf方法 - 干净的原型链 先说简单的getPrototypeOf方法,这个方法统一了获取对象原型的方式,使用这个对象可以获取到对象的原型,这个不多说了.

前端基础-JavaScript的基本概述和语法

1.JavaScript概述 2.JavaScript引入方式 3.JavaScript语言规范 4.JavaScript语言基础 5.JavaScript数据类型 6.JavaScript运算符 7.JavaScript流程控制 8.JavaScript函数 9.JavaScript词法分析 10.JavaScript内置对象和方法 一.JavaScript概述 1.ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将

JavaScript的对象概述

一.JavaScript对象的概述: 1.什么是对象,其实就是一种类型,即引用类型.而对象的值就是引用类型的实例. 2.在javaScript 中引用类型是一种数据结构,用于将数据和功能组织在一起.它也常被称做为类,但 javaScript 中却没有这种东西(模拟). 3.虽然 javaScript 是一门面向对象的语言,却不具备传统面向对象语言所支持的类和接口等基本结构. 4.在应用程序中的存储和传输数据而言,它是非常理想的选择. 二.javaScript对象的创建: 创建 Object 类型

JavaScript 常用功能总结

编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的额JS 对象,基本数据结构,功能函数等,还有一些常用的设计模式. 目录: 众所周知,JavaScript是动态的面向对象的编程语言,能够实现以下效果: 1. 丰富Web 网页功能 2. 丰富Web界面 3. 实现本地或远程存储. 4. 实现分布式网络应用的前端组件,并在后台进行数据存储管理. 5. 使用JavaScript可以实现完整的分布式Web 应用. JavaScript 中的数据类型 Ja

JavaScript 对象的概述

JavaScript 对象的概述 最简单的概述:在JavaScript中对象仅仅是属性的容器. 每个对象都可以有零个或多个属性值, 这些属性持有一个基本类型的值,也可以是持有一个对象引用. JavaScript中创建对象的常见方法 JavaScript中常见的常见对象的方式有三种: . 使用对象字面量 var obj = {} . 使用new运算符 var obj = new Object() . 使用create()函数 var obj = Object.create(null); 这三种创建

js版本规范的表示:ES6 == ES 6 == ECMAScript 6 == ECMA-262 6

Ecma 国际大会宣布正式批准ECMA-262第 6 版,亦即 ECMAScript 2015(曾用名:ECMAScript 6.ES6)的语言规范. 关系 ECMA-262 == ECMAScript Ed表示 ES6 == ES 6 == ECMAScript 6 == ECMA-262 6 Ed.6 年号表示 ES6 == ECMAScript 2015 Written by Lee Boonstra JavaScript’s competing versions of the langu

Zabbix功能概述及架构介绍(理论篇)

1.Zabbix的功能概述 1.1 zabbix是什么 Alexei Vladishev创建了Zabbix项目,当前处于活跃的开发状态,Zabbix SIA提供支持. Zabbix是一个企业级的.开源的.分布式的监控套件. Zabbix可以对网络和服务进行监控. Zabbix利用灵活的告警机制,可实现微信.短信和邮件的自动报警.Zabbix利用存储的监控数据提供监控报告及实现图形化显示. Zabbix支持polling和trapping两种方式.所有的Zabbix报告都可以通过配置参数在WEB界