博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
这些是您应该知道的ES6中的功能
阅读量:2524 次
发布时间:2019-05-11

本文共 18215 字,大约阅读时间需要 60 分钟。

was named one of the !

被评为

ES6 brings more features to the JavaScript language. Some new syntax allows you to write code in a more expressive way, some features complete the functional programming toolbox, and some features are questionable.

ES6为JavaScript语言带来了更多功能。 一些新的语法允许您以更具表现力的方式编写代码,一些功能完善了功能性编程工具箱,而某些功能则值得怀疑。

let和const (let and const)

There are two ways for declaring a variable (let and const) plus one that has become obsolete (var).

有两种声明变量的方法( letconst ),还有一种已经过时的变量( var )。

(let)

let declares and optionally initializes a variable in the current scope. The current scope can be either a module, a function or a block. The value of a variable that is not initialized is undefined .

let声明并可选地初始化当前范围内的变量。 当前作用域可以是模块,功能或块。 未初始化的变量的值是undefined

Scope defines the lifetime and visibility of a variable. Variables are not visible outside the scope in which they are declared.

范围定义变量的生存期和可见性。 变量在声明范围之外不可见。

Consider the next code that emphasizes let block scope:

考虑下一个强调let块作用域的代码:

let x = 1;{   let x = 2;}console.log(x); //1

In contrast, the var declaration had no block scope:

相反, var声明没有块作用域:

var x = 1;{   var x = 2;}console.log(x); //2

The for loop statement, with the let declaration, creates a new variable local to the block scope, for each iteration. The next loop creates five closures over five different i variables.

带有let声明的for循环语句为每次迭代创建一个位于块作用域局部的新变量。 下一个循环在五个不同的i变量上创建五个闭包。

(function run(){  for(let i=0; i<5; i++){    setTimeout(function log(){      console.log(i); //0 1 2 3 4    }, 100);  }})();

Writing the same code with var will create five closures, over the same variable, so all closures will display the last value of i.

var编写相同的代码将在同一个变量上创建五个闭包,因此所有闭包将显示i的最后一个值。

The log() function is a closure. For more on closures, take a look at .

log()函数是一个闭包。 有关闭包的更多信息,请 。

const (const)

const declares a variable that cannot be reassigned. It becomes a constant only when the assigned value is immutable.

const声明了一个不能重新分配的变量。 仅当分配的值不可变时,它才变为常数。

An immutable value is a value that, once created, cannot be changed. Primitive values are immutable, objects are mutable.

不变值是一旦创建就无法更改的值。 原始值是不可变的,对象是可变的。

const freezes the variable, Object.freeze() freezes the object.

const冻结变量, Object.freeze()冻结对象。

The initialization of the const variable is mandatory.

const变量的初始化是强制性的。

模组 (Modules)

Before modules, a variable declared outside any function was a global variable.

在模块之前,在任何函数外部声明的变量是全局变量。

With modules, a variable declared outside any function is hidden and not available to other modules unless it is explicitly exported.

对于模块,在任何函数外部声明的变量都将被隐藏,并且除非明确导出,否则其他模块无法使用。

Exporting makes a function or object available to other modules. In the next example, I export functions from different modules:

导出使功能或对象可用于其他模块。 在下一个示例中,我从不同的模块导出函数:

//module "./TodoStore.js"export default function TodoStore(){}//module "./UserStore.js"export default function UserStore(){}

Importing makes a function or object, from other modules, available to the current module.

导入使其他模块的功能或对象可用于当前模块。

import TodoStore from "./TodoStore";import UserStore from "./UserStore";const todoStore = TodoStore();const userStore = UserStore();

传播/休息 (Spread/Rest)

The operator can be the spread operator or the rest parameter, depending on where it is used. Consider the next example:

运算符可以是传播运算符,也可以是rest参数,具体取决于使用位置。 考虑下一个示例:

const numbers = [1, 2, 3];const arr = ['a', 'b', 'c', ...numbers];console.log(arr);["a", "b", "c", 1, 2, 3]

This is the spread operator. Now look at the next example:

这是点差运算符。 现在看下一个例子:

function process(x,y, ...arr){  console.log(arr)}process(1,2,3,4,5);//[3, 4, 5]function processArray(...arr){  console.log(arr)}processArray(1,2,3,4,5);//[1, 2, 3, 4, 5]

This is the rest parameter.

这是rest参数。

论点 (arguments)

With the rest parameter we can replace the arguments pseudo-parameter. The rest parameter is an array, arguments is not.

使用rest参数,我们可以替换arguments伪参数。 rest参数是一个数组, arguments不是。

function addNumber(total, value){  return total + value;}function sum(...args){  return args.reduce(addNumber, 0);}sum(1,2,3); //6

克隆 (Cloning)

The spread operator makes the cloning of objects and arrays simpler and more expressive.

传播运算符使对象和数组的克隆更加简单和更具表现力。

The object spread properties operator will be available as part of ES2018.

对象传播属性运算符将作为ES2018的一部分提供。

const book = { title: "JavaScript: The Good Parts" };//clone with Object.assign()const clone = Object.assign({}, book);//clone with spread operatorconst clone = { ...book };const arr = [1, 2 ,3];//clone with sliceconst cloneArr = arr.slice();//clone with spread operatorconst cloneArr = [ ...arr ];

级联 (Concatenation)

In the next example, the spread operator is used to concatenate arrays:

在下一个示例中,spread运算符用于连接数组:

const part1 = [1, 2, 3];const part2 = [4, 5, 6];const arr = part1.concat(part2);const arr = [...part1, ...part2];

合并物件 (Merging objects)

The spread operator, like Object.assign(), can be used to copy properties from one or more objects to an empty object and combine their properties.

Object.assign()这样的散布运算符可用于将属性从一个或多个对象复制到一个空对象并组合其属性。

const authorGateway = {   getAuthors : function() {},  editAuthor: function() {}};const bookGateway = {   getBooks : function() {},  editBook: function() {}};//copy with Object.assign()const gateway = Object.assign({},      authorGateway,       bookGateway);      //copy with spread operatorconst gateway = {   ...authorGateway,   ...bookGateway};

物业速记 (Property short-hands)

Consider the next code:

考虑下一个代码:

function BookGateway(){  function getBooks() {}  function editBook() {}    return {    getBooks: getBooks,    editBook: editBook  }}

With property short-hands, when the property name and the name of the variable used as the value are the same, we can just write the key once.

使用属性简写,当属性名称和用作值的变量名称相同时,我们只需编写一次键。

function BookGateway(){  function getBooks() {}  function editBook() {}    return {    getBooks,    editBook  }}

Here is another example:

这是另一个示例:

const todoStore = TodoStore();const userStore = UserStore();    const stores = {  todoStore,  userStore};

销毁工作 (Destructuring assignment)

Consider the next code:

考虑下一个代码:

function TodoStore(args){  const helper = args.helper;  const dataAccess = args.dataAccess;  const userStore = args.userStore;}

With destructuring assignment syntax, it can be written like this:

使用解构分配语法,可以这样编写:

function TodoStore(args){   const {       helper,       dataAccess,       userStore } = args;}

or even better, with the destructuring syntax in the parameter list:

甚至更好,使用参数列表中的解构语法:

function TodoStore({ helper, dataAccess, userStore }){}

Below is the function call:

下面是函数调用:

TodoStore({   helper: {},   dataAccess: {},   userStore: {} });

默认参数 (Default parameters)

Functions can have default parameters. Look at the next example:

函数可以具有默认参数。 看下一个例子:

function log(message, mode = "Info"){  console.log(mode + ": " + message);}log("An info");//Info: An infolog("An error", "Error");//Error: An error

模板字符串文字 (Template string literals)

Template strings are defined with the ` character. With template strings, the previous logging message can be written like this:

模板字符串用`字符定义。 使用模板字符串,以前的日志记录消息可以这样写:

function log(message, mode= "Info"){  console.log(`${mode}: ${message}`);}

Template strings can be defined on multiple lines. However, a better option is to keep the long text messages as resources, in a database for example.

模板字符串可以在多行中定义。 但是,更好的选择是将长文本消息保留为资源,例如在数据库中。

See below a function that generates an HTML that spans multiple lines:

参见下面的函数,该函数生成跨多行HTML:

function createTodoItemHtml(todo){  return `
  • ${todo.title}
    ${todo.userName}
  • `;}

    正确的尾声 (Proper tail-calls)

    A recursive function is tail recursive when the recursive call is the last thing the function does.

    当递归调用是函数执行的最后一件事时,递归函数就是尾部递归。

    The tail recursive functions perform better than non tail recursive functions. The optimized tail recursive call does not create a new stack frame for each function call, but rather uses a single stack frame.

    尾部递归函数的性能优于非尾部递归函数。 优化的尾部递归调用不会为每个函数调用创建新的堆栈框架,而是使用单个堆栈框架。

    ES6 brings the tail-call optimization in strict mode.

    ES6在严格模式下实现了尾部呼叫优化。

    should benefit from the tail-call optimization.

    应受益于尾部调用优化。

    function print(from, to) {   const n = from;  if (n > to)  return;    console.log(n);      //the last statement is the recursive call   print(n + 1, to); }print(1, 10);

    Note: the tail-call optimization is not yet supported by major browsers.

    注意:主要浏览器尚不支持尾部调用优化。

    承诺 (Promises)

    A promise is a reference to an asynchronous call. It may resolve or fail somewhere in the future.

    Promise是对异步调用的引用。 它可能在将来某个地方解决或失败。

    Promises are easier to combine. , it is easy to call a function when all promises are resolved, or when the first promise is resolved.

    承诺更容易合并。 当所有promise都解决了,或者第一个promise解决了,就很容易调用函数。

    function getTodos() { return fetch("/todos"); }function getUsers() { return fetch("/users"); }function getAlbums(){ return fetch("/albums"); }const getPromises = [  getTodos(),   getUsers(),   getAlbums()];Promise.all(getPromises).then(doSomethingWhenAll);Promise.race(getPromises).then(doSomethingWhenOne);function doSomethingWhenAll(){}function doSomethingWhenOne(){}

    The fetch() function, part of the Fetch API, returns a promise.

    作为Fetch API一部分的fetch()函数返回一个promise。

    Promise.all() returns a promise that resolves when all input promises have resolved. Promise.race() returns a promise that resolves or rejects when one of the input promises resolves or rejects.

    Promise.all()返回一个承诺,当所有输入的Promise.all()都解决后, Promise.all()解决。 Promise.race()返回一个承诺,当输入的一个promise解析或拒绝时,它会解析或拒绝。

    A promise can be in one of the three states: pending, resolved or rejected. The promise will in pending until is either resolved or rejected.

    承诺可以处于以下三种状态之一:未决,已解决或已拒绝。 承诺将待定,直到被解决或被拒绝。

    Promises support a chaining system that allows you to pass data through a set of functions. , the result of getTodos() is passed as input to toJson(), then its result is passed as input to getTopPriority(), and then its result is passed as input to renderTodos() function. When an error is thrown or a promise is rejected the handleError is called.

    Promises支持一个链接系统,该系统允许您通过一组功能传递数据。 ,将getTodos()的结果作为输入传递给toJson() ,然后将其结果作为输入传递给getTopPriority() ,然后将其结果作为输入传递给renderTodos()函数。 当引发错误或拒绝承诺时,将handleError

    getTodos()  .then(toJson)  .then(getTopPriority)  .then(renderTodos)  .catch(handleError);function toJson(response){}function getTopPriority(todos){}function renderTodos(todos){}function handleError(error){}

    In the previous example, .then() handles the success scenario and .catch() handles the error scenario. If there is an error at any step, the chain control jumps to the closest rejection handler down the chain.

    在前面的例子, .then()处理成功场景和.catch()处理错误的情况。 如果任何步骤有错误,链控制将跳至链中最接近的拒绝处理程序。

    Promise.resolve() returns a resolved promise. Promise.reject() returns a rejected promise.

    Promise.resolve()返回已解决的Promise.resolve()Promise.reject()返回被拒绝的承诺。

    (Class)

    Class is sugar syntax for creating objects with a custom prototype. It has a better syntax than the previous one, the function constructor. :

    类是用于使用自定义原型创建对象的糖语法。 它比以前的函数构造函数具有更好的语法。 :

    class Service {  doSomething(){ console.log("doSomething"); }}let service = new Service();console.log(service.__proto__ === Service.prototype);

    All methods defined in the Service class will be added to theService.prototype object. Instances of the Service class will have the same prototype (Service.prototype) object. All instances will delegate method calls to the Service.prototype object. Methods are defined once onService.prototype and then inherited by all instances.

    Service类中定义的所有方法都将添加到Service.prototype对象。 Service类的实例将具有相同的原型( Service.prototype )对象。 所有实例都将方法调用委托给Service.prototype对象。 方法在Service.prototype上定义一次,然后被所有实例继承。

    遗产 (Inheritance)

    “Classes can inherit from other classes”. Below is an where the SpecialService class “inherits” from the Service class:

    “类可以从其他类继承”。 下面是一个其中SpecialService类从Service类“继承”:

    class Service {  doSomething(){ console.log("doSomething"); }}class SpecialService extends Service {  doSomethingElse(){ console.log("doSomethingElse"); }  }let specialService = new SpecialService();specialService.doSomething();specialService.doSomethingElse();

    All methods defined in the SpecialService class will be added to the SpecialService.prototype object. All instances will delegate method calls to the SpecialService.prototype object. If the method is not found in SpecialService.prototype, it will be searched in the Service.prototypeobject. If it is still not found, it will be searched in Object.prototype.

    SpecialService类中定义的所有方法都将添加到SpecialService.prototype对象。 所有实例都将方法调用委托给SpecialService.prototype对象。 如果在SpecialService.prototype找不到该方法,则将在Service.prototype对象中对其进行搜索。 如果仍然找不到,将在Object.prototype搜索Object.prototype

    上课可能成为坏功能 (Class can become a bad feature)

    Even if they seem encapsulated, all members of a class are public. You still need to manage problems with this losing context. The public API is mutable.

    即使它们看起来是封装的,类的所有成员也是公开的。 您仍然需要在this丢失的环境中管理问题。 公共API是可变的。

    class can become a bad feature if you neglect the functional side of JavaScript. class may give the impression of a class-based language when JavaScript is both a functional programming language and a prototype-based language.

    如果您忽略了JavaScript的功能方面,则class可能会成为一个坏功能。 当JavaScript既是功能编程语言又是基于原型的语言时, class可能给人以基于类的语言的印象。

    Encapsulated objects can be created with factory functions. Consider the next example:

    封装的对象可以使用工厂功能创建。 考虑下一个示例:

    function Service() {  function doSomething(){ console.log("doSomething"); }    return Object.freeze({     doSomething  });}

    This time all members are private by default. The public API is immutable. There is no need to manage issues with this losing context.

    这次默认情况下,所有成员都是私有的。 公共API是不可变的。 在this丢失的情况下,无需管理问题。

    class may be used as an exception if required by the components framework. This was the case with React, but is not the case anymore with .

    如果组件框架要求,则可以将class用作异常。 React就是这种情况,但是不再是这种情况。

    For more on why to favor factory functions, take a look at .

    有关为什么偏爱工厂功能的更多信息,请查看 。

    箭头功能 (Arrow functions)

    Arrow functions can create anonymous functions on the fly. They can be used to create small callbacks, with a shorter syntax.

    箭头函数可以动态创建匿名函数。 它们可用于创建使用较短语法的小型回调。

    Let’s take a collection of to-dos. A to-do has an id , a title , and a completed boolean property. Now, consider the next code that selects only the title from the collection:

    让我们收集待办事项。 待办事项具有idtitlecompleted boolean属性。 现在,考虑下一个仅从集合中选择title代码:

    const titles = todos.map(todo => todo.title);

    or the next example selecting only the todos that are not completed:

    或以下示例仅选择未完成的todos

    const filteredTodos = todos.filter(todo => !todo.completed);

    这个 (this)

    Arrow functions don’t have their own this and arguments. As a result, you may see the arrow function used to fix problems with this losing context. I think that the best way to avoid this problem is to not use this at all.

    Arrow函数没有自己的thisarguments 。 如此一来,您可能会看到用于修复this丢失上下文问题的箭头功能。 我认为避免此问题的最佳方法是根本不使用this

    箭头功能可能会成为一个坏功能 (Arrow functions can become a bad feature)

    Arrow functions can become a bad feature when used to the detriment of named functions. This will create readability and maintainability problems. Look at the next code written only with anonymous arrow functions:

    当使用箭头函数损害命名函数时,它可能会成为一个不好的功能。 这将产生可读性和可维护性问题。 查看仅使用匿名箭头功能编写的下一个代码:

    const newTodos = todos.filter(todo =>        !todo.completed && todo.type === "RE")    .map(todo => ({       title : todo.title,       userName : users[todo.userId].name    }))    .sort((todo1, todo2) =>        todo1.userName.localeCompare(todo2.userName));

    refactored to pure functions with intention revealing names and decide which of them is easier to understand:

    意图重构名称的重构为纯函数 ,并确定其中哪个更容易理解:

    const newTodos = todos.filter(isTopPriority)  .map(partial(toTodoView, users))  .sort(ascByUserName);function isTopPriority(todo){  return !todo.completed && todo.type === "RE";}  function toTodoView(users, todo){  return {    title : todo.title,    userName : users[todo.userId].name  }}function ascByUserName(todo1, todo2){  return todo1.userName.localeCompare(todo2.userName);}

    Even more, anonymous arrow functions will appear as (anonymous) in the Call Stack.

    甚至更多,匿名箭头功能在调用堆栈中将显示为(anonymous)

    For more on why to favor named functions, take a look at .

    有关为什么偏爱命名函数的更多信息,请参阅 。

    Less code doesn’t necessary mean more readable. and see which version is easier for you to understand:

    更少的代码并不一定意味着更具可读性。 ,看看哪个版本更容易理解:

    //with arrow functionconst prop = key => obj => obj[key];//with function keywordfunction prop(key){   return function(obj){      return obj[key];   }}

    Pay attention when returning an object. In the next example, the getSampleTodo() returns undefined.

    返回对象时要注意。 在下一个示例中, getSampleTodo()返回undefined

    const getSampleTodo = () => { title : "A sample todo" };getSampleTodo();//undefined

    发电机 (Generators)

    I think the ES6 generator is an unnecessary feature that makes code more complicated.

    我认为ES6生成器是不必要的功能,它会使代码更加复杂。

    The ES6 generator creates an object that has the next() method. The next() method creates an object that has the value property. ES6 generators promote the use of loops. :

    ES6生成器创建一个具有next()方法的对象。 next()方法创建一个具有value属性的对象。 ES6生成器促进使用循环。 :

    function* sequence(){  let count = 0;  while(true) {    count += 1;    yield count;  }}const generator = sequence();generator.next().value;//1generator.next().value;//2generator.next().value;//3

    The same generator can be simply implemented with a closure.

    可以使用闭包简单地实现同一生成器。

    function sequence(){  let count = 0;  return function(){    count += 1;    return count;  }}const generator = sequence();generator();//1generator();//2generator();//3

    For more examples with functional generators take a look at .

    有关使用函数生成器的更多示例,请看 。

    结论 (Conclusion)

    let and const declare and initialize variables.

    letconst声明并初始化变量。

    Modules encapsulate functionality and expose only a small part.

    模块封装了功能,只公开了一小部分。

    The spread operator, rest parameter, and property shorthand make things easier to express.

    传播算子,rest参数和属性速记使事情更容易表达。

    Promises and tail recursion complete the functional programming toolbox.

    承诺和尾递归完善了功能性编程工具箱。

    was named one of the !

    被称为

    For more on applying functional programming techniques in React take a look at .

    有关在React中应用函数式编程技术的更多信息,请查看

    Learn functional React, in a project-based way, with .

    通过 ,以基于项目的方式学习功能性React

    翻译自:

    转载地址:http://ufwzd.baihongyu.com/

    你可能感兴趣的文章
    根据现有表操作基于active record的model
    查看>>
    NotMapped属性特性
    查看>>
    Count and Say
    查看>>
    GridView数据导入Excel/Excel数据读入GridView
    查看>>
    566. Reshape the Matrix
    查看>>
    python数据结构与算法之搜索
    查看>>
    (最小点覆盖) poj 2226
    查看>>
    (树形DP) poj 3659
    查看>>
    获取类的属性名和值
    查看>>
    python对json的操作总结
    查看>>
    学习进度表第十一周
    查看>>
    js屏蔽回车键
    查看>>
    Memcached通用类(基于enyim.com Memcached Client)
    查看>>
    c#组元(Tuple)的使用
    查看>>
    【NO.66】转 Yahoo的军规条例
    查看>>
    vim基础学习之搜索功能
    查看>>
    session和cookie
    查看>>
    tftp 开发板ping不通PC机
    查看>>
    未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”
    查看>>
    Erdos
    查看>>