ES7和 ES8 一览

news/2023/11/28 18:55:55

ES7

Array.prototype.includes

在es5 或者 es6 中我们要判断数组中是否包含某个元素我们需要用到Array.prototype.indexOf,在es7中加入了
arr.includes(searchElement, fromIndex)

以前我们需要这么写

let arr = ['react', 'angular', 'vue']
// Correct
if (arr.indexOf('react') !== -1) {console.log('Can use React')
}

也许有的人知道使用**~**,但是可读性不是很好.

    let arr = ['react', 'angular', 'vue']// Correctif (~arr.indexOf('react')) {console.log('Can use React')}

所以现在提供了

Array.prototype.includes. 

这样的方式直观。可读性强

let arr = ['react', 'angular', 'vue']
// Correct
if (arr.includes('react')) {console.log('Can use React')
}
//use in string.
// Correct
if (arr.includes('react')) {console.log('Can use React')
}

es7仅仅只有两个新的成员加入另外一个就是
指数运算符 **

let a = 7 ** 12
let b = 2 ** 7
console.log(a === Math.pow(7,12)) // true
console.log(b === Math.pow(2,7)) 

ES8

在es8中主要有6个特性:
主要的有:

  • Shared memory and atomics (共享内存和原子)
  • Async Functions(异步函数)

其他的特性:

  • Object.values/Object.entries (配合Object.keys使用)
  • String padding (字符串填充)
  • Object.getOwnPropertyDescriptors()
  • Trailing commas in function parameter lists and calls(在函数参数列表和调用中减少逗号的使用)

首先我们来介绍一下主要的两个特性:

Shared memory and atomics (共享内存和原子)

在我们先需要主要需要了解SharedArrayBuffer 和 Atomics

SharedArrayBuffer

在了解SharedArrayBuffer 之前我们需要了解下需要share的这个ArrayBuffer:

ArrayBuffer对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写,视图的作用是以指定格式解读二进制数据。这个接口的原始设计目的,与 WebGL 项目有关。所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足 JavaScript 与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个32位整数,两端的 JavaScript 脚本与显卡都要进行格式转化,将非常耗时。这时要是存在一种机制,可以像 C 语言那样,直接操作字节,将4个字节的32位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。

那么我们为什么需要SharedArrayBuffer这个function呢?
任何能够从主线程负载减少工作的方法都对代码运行效率有帮助,某些情况下,ArrayBuffers 可以减少大量应该由主线程做的工作(免去了格式转换的耗时和压力直接操作字符),但是也有些时候减少主线程负载是远远不够的,有时你需要增援,你需要分割你的任务,那么我们这个时候就需要传说中的多线程。
在 JavaScript 里,你可以借助 web worker 做这种事,但是web worker是不能共享内存的,那么这意味着如果你想分配你的任务给别的线程,你需要完整把任务复制过去,这可以通过 postMessage 实现,postMessage 把你传给它的任何对象都序列化,发送到其它 web worker,然后那边接收后反序列化并放进内存。可见这个过程也是相当慢的。我们下面来看下这个过程的code [from MDN]:

main.js

var first = document.querySelector('#number1');
var second = document.querySelector('#number2');var result = document.querySelector('.result');if (window.Worker) { // Check if Browser supports the Worker api.// Requires script name as inputvar myWorker = new Worker("worker.js");// onkeyup could be used instead of onchange if you wanted to update the answer every time
// an entered value is changed, and you don't want to have to unfocus the field to update its .valuefirst.onchange = function() {myWorker.postMessage([first.value,second.value]); // Sending message as an array to the workerconsole.log('Message posted to worker');};second.onchange = function() {myWorker.postMessage([first.value,second.value]);console.log('Message posted to worker');};myWorker.onmessage = function(e) {result.textContent = e.data;console.log('Message received from worker');};
}

worker.js

onmessage = function(e) {console.log('Message received from main script');var workerResult = 'Result: ' + (e.data[0] * e.data[1]);console.log('Posting message back to main script');postMessage(workerResult);
}

从上面的code可以看出这样传来传去是非常慢的。
那么我们想多个 web worker 就可以同时读写同一块内存,这样我们就不用传来传去的了,这就是SharedArrayBuffers 为我们提供的。
我们来看下使用使用shareArrayBuffers是怎样实现这个乘法的

main.js

"use strict";
var first = document.querySelector('#number1');
var second = document.querySelector('#number2');var result = document.querySelector('.result');if (window.Worker) { // Check if Browser supports the Worker api.// Requires script name as inputvar myWorker = new Worker("worker.js");// onkeyup could be used instead of onchange if you wanted to update the answer every time
// an entered value is changed, and you don't want to have to unfocus the field to update its .valuevar sharedBuffer = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);first.onchange = function() {addNumber();}second.onchange = function() {addNumber();};const addNumber = () => {myWorker.postMessage({aTopic: [first.value, second.value],aBuf: sharedBuffer // The array buffer that we passed to the transferrable section 3 lines below});console.log('Message posted to worker');result.textContent = new Int32Array(sharedBuffer)[0];console.log('Message received from worker');}
}

worker.js

onmessage = function(e) {console.log('Message received from main script');var workerResult = e.data.aTopic[0] * e.data.aTopic[1];new Int32Array(e.data.aBuf)[0] = workerResult;
}

我们这个时候也不用担心postMessage 伴有时延的通信。但是多个worker同时访问一块内存这个时候会出现竞争的问题的。
从 CPU 层面看,增加一个变量值需要三条指令,这是因为计算机同时有长期存储器(内存)和短期存储器(寄存器所有的线程共享同一个长期存储器(内存),但是短期存储器(寄存器)并不是共享的。每个线程需要把值先从内存搬到寄存器,之后就可以在寄存器上进行计算了,再然后会把计算后的值写回内存)。
在这里插入图片描述

这个因为竞争的关系会产生错误的结果,那么我们应该怎样让SharedArrayBuffers 发挥他应有的价值呢?
这个时候伴随它诞生的还有:

Atomics

原子操作做的一件事就是在多线程中让计算机按照人所想的单操作方式工作。
这就是为什么被叫做原子操作,因为它可以让一个包含多条指令(指令可以暂停和恢复)的操作执行起来像是一下子就完了,就好像一条指令,类似一个不可分割的原子。

var sab = new SharedArrayBuffer(1024);
var ta = new Uint8Array(sab);
//The static Atomics.add() method adds a given value at a given //position in the array and returns the old value at that position.
Atomics.add(ta, 0, 1); // returns 0, the old value
Atomics.load(ta, 0); // 1

async 函数

首先我们来看下在async 函数诞生之前我们是怎么处理异步的,我先简单列举几个编程模型:
回调函数:

// more code
function loading(callback) {// wait 3ssetTimeout(function () {callback();}, 3000);
}
function show() {// show the data.
}
loading(show);
// more code

在这种情况下容易出现大家所熟知的回调黑洞:

A(function () {B(function () {C(function() {D(function() {// ...})})})
})

Promise模式
所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

let promise = new Promise(function(resolve, reject) {console.log('Promise');resolve();
});promise.then(function() {console.log('Resolved.');
});console.log('Hi!');// Promise
// Hi!
// Resolved

这种实现方式和AngularJs中的Promise用法相近。
下面简单提下ES6中的Generator 函数的使用:

function* gen(x) {var y = yield x + 2;return y;
}var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true }

gen函数返回不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object)。
其实在ES8之前我们还有许多其他的异步实现方式,比如:
在angualrJs中我们实现的subscribe, unsubscribe, publish这种消息订阅/发布模式其实也是实现异步的一种方式。
下面我们来说说今天的主角:async 函数
关键词:await async
那么我们先看下await, await后面可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作),当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。
我们看下下面的代码来理解上面的话:

function resolveAfter2Seconds(x) {return new Promise(resolve => {setTimeout(() => {resolve(x);}, 2000);});
}async function add(x) {var a = await resolveAfter2Seconds(20);var b = await resolveAfter2Seconds(30);return x + a + b;
}add(10).then(v => {console.log(v);  // prints 60 after 4 seconds.
});

Object.values/Object.entries

ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的所有可遍历(enumerable)属性的键名。

var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

es8中新添加的Object.values/Object.entries作为遍历对象的一种补充手段。
Object.values方法返回一个数组,成员是参数对象自身的所有可遍历(enumerable)属性的键值。

var obj = { 100: 'a', 'a': 'b', 7: 'c' };
Object.values(obj)
// ["c", "a", "b"]

Object.entries方法返回一个数组,成员是参数对象自身的所有可遍历(enumerable)属性的键值对数组。

var obj = { 'foo': 'bar', 'baz': 42 , '1': 43};
Object.entries(obj)
// [['1', 43], ["foo", "bar"], ["baz", 42] ]

以上的遍历对象的属性,都遵守同样的属性遍历的次序规则。
首先遍历所有属性名为数值的属性,按照数字排序。
其次遍历所有属性名为字符串的属性,按照生成时间排序。
最后遍历所有属性名为 Symbol 值的属性,按照生成时间排序。
(Object.keys,Object.values,Object.entries都会过滤属性名为 Symbol(一种新的原始数据类型, 表示独一无二的值) 值的属性。)

String padding

字符填充函数,在es8中引入的两个方法: String.padStart 和String.padEnd, 这两个放发的主要是为了在一定程度上填充字符串的长度, 语法如下:

str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])

这个方法主要是为了实现字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'//如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'//如果省略第二个参数,默认使用空格补全长度。
'x'.padStart(4) // '   x'
'x'.padEnd(4) // 'x   '//用途: 为数值补全指定位数。
'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"//另一个用途是提示字符串格式。
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

getOwnPropertyDescriptors函数

getOwnPropertyDescriptors函数: 返回指定对象所有自身属性(非继承属性)的描述对象。
ES5 有一个Object.getOwnPropertyDescriptor方法,返回某个对象属性的描述对象(descriptor)。

var obj = { p: 'a' };Object.getOwnPropertyDescriptor(obj, 'p')
// Object { value: "a",
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

ES2017 引入了Object.getOwnPropertyDescriptors方法,返回指定对象所有自身属性(非继承属性)的描述对象。

const obj = {foo: 123,get bar() { return 'abc' }
};Object.getOwnPropertyDescriptors(obj)
// { foo:
//    { value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//   bar:
//    { get: [Function: bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true } }

value
包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。该特性的默认值为undefined。直接在对象上定义的属性,该特性被设置为指定的值

writable
表示能否修改属性的值。直接在对象上定义的属性,该特性默认为true

get
获取该属性的访问器函数(getter)。如果没有访问器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)

set
获取该属性的设置器函数(setter)。 如果没有设置器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)

configurable
表示能否通过delete删除属性从而重新定义属性。,能否修改属性的特性,或者能否把属性修改为访问器属性。直接在对象上定义的属性,该特性默认为true;

enumerable
表示能否通过for-in循环返回属性。直接在对象上定义的属性,该特性默认为true

应用:浅拷贝

const shallowClone = (obj) => Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj)
);

在装饰器上应用

Trailing commas in function parameter lists and calls(结尾逗号)

此处结尾逗号指的是在函数参数列表中最后一个参数之后的逗号以及函数调用时最后一个参数之后的逗号。ES8 允许在函数定义或者函数调用时,最后一个参数之后存在一个结尾逗号而不报 SyntaxError 的错误。示例代码如下:

函数声明时

function es8(var1, var2, var3,) {// ...
}

函数调用时
es8(10, 20, 30,);
ES8的这项新特性受启发于对象或者数组中最后一项内容之后的逗号,如 [10, 20, 30,] 和 { x: 1, } 。


http://www.ppmy.cn/news/131428.html

相关文章

ES7与ES8特性

我曾写过一篇关于ES6博客《10个最佳ES6特性》,这次我打算聊聊ES7和ES8特性。 ES7只有2个特性: includes()指数操作符 ES8尚未发布(2017年1月),下面是它已经完成起草的一些特性: Object.values()Object.entries()padStart()padEnd()Object…

ES7, ES8

文章目录 前言一、ES7(一) includes() 二、ES8(一)Object.values()1. 意义:遍历对象对的属性值,需要通过属性名key去获取属性值2. 例如:-->ES8前-->ES8后 (二)Obje…

Elasticsearch:使用标准 Java HTTP 的集成 - Elastic Stack 8.x

Elasticsearch 功能可以通过多种方式轻松集成到任何 Java 应用程序中,通过 REST API 或通过本机 API。 在 Java 中,很容易使用许多可用库之一调用 REST HTTP 接口,例如 Apache HttpComponents 客户端(有关更多信息,请参…

ES6, ES7, ES8, ES9 以及 ES10 新特征

目录 1. ES6 新特征 (2015) 1.1 module 1.1.1 export 1.1.2 import 1.2 Arrow function (箭头函数) 1.2.1 箭头函数结构 1.3 默认参数 1.4 模板字符串 1.5. 解构赋值 1.5.1数组的结构赋值 1.5.2 对象解构赋值 1.6 扩展运算符 1.7Promise(异步) 2 ES7新特征 (2016…

【ES】elasticsearch常见报错(服务端)

elasticsearch常见报错 _search 操作响应错误Cannot search on field [xxxxx] since it is not indexed.unknown type for collapse field ‘xxx’, only keywords and numbers are accepted _search 操作响应错误 Cannot search on field [xxxxx] since it is not indexed. …

ES新语法ES7、ES8、ES9、ES10新特性

ES7新特性 1.Array.prototype.includes()方法 //直观判断数组中是否包含一个元素,,如果包含则返回true,否则返回false。 const arr [1, 3, 5, 2, 8, NaN, -0] arr.includes(1) // true arr.includes(1, 2) // false 该方法的第二个参数表示搜索的起始…

ES6、ES7、ES8、ES9、ES10、ES11

目录 一、ES6 二、ES7 三、ES8 四、ES9 一、ES6 点击跳转 二、ES7 1.Includes方法:检测数组是否包含某个元素,返回布尔值 const mingzhu [西游记, 红楼梦, 三国演义, 水浒传]; console.log(mingzhu.includes(西游记)); // true console.log(min…

android系统能内存卡,手机SD卡可以作为内置存储吗? 安卓6.0将支持microSD卡作为内置存储...

过去不少厂商为了引导用户选择存储空间更大更昂贵的机型,纷纷取消了外置存储卡的功能。然而大部分用户自始至终都更青睐支持外置存储卡的手机,这也迫使手机厂商调整策略。现在就连一向排斥外置存储卡的谷歌也在安卓6.0中加入了将外置存储卡作为内置存储的…

linux检测扩容卡,TF内存卡是不是扩容卡准确质量检测

如果你花了很少的钱买了一个非常大容量的内存卡,那么就要小心了,你可能买到的是一个扩容的内存卡,所谓扩容就是说容量的虚拟的,真实容量可能只有一成不到,比如64G的内存卡,实际容量可能只有4G,那…

linux检测扩容卡,教你检测SD卡内存卡是否被扩容过的方法

新购买一个便宜的内存卡,使用一段时间后,发现不能存东西了,或者不能再读了,怎么回事呢?其实发生这些问题就是SD卡内存卡烧了。其实很多人购买便宜内存卡多半是扩容的,实际容量不到标称容量的1/4。那么如何检…

android 手机存储位置设置,如何将红米手机外置SD卡设定为默认存储

在国产机中,小米的地位越来越具优势,低价高配已经成为了小米手机的代言词,799元的红米手机最能说明问题,红米手机已经销售了有一段时间了,随之而来的一些小问题让用户有些头疼,其中包括无法将外置SD卡设定为…

手机闪存速度排行_手机很卡可能是只是因为闪存颗粒太差 EMMC UFS大对比

原标题:手机很卡可能是只是因为闪存颗粒太差 EMMC UFS大对比 在经历了华为的“闪存门”事件以后,人们都开始关注关于手机内存的相关知识。那么所谓的EMMC和UFC到底有什么差别,那一个更好一些呢?接下来我们将仔细讲解。 大众了解到…

用计算机读取机读卡信息,摄像机SD卡无法读取怎么办

一般用摄像机摄像的时候都是在发生比较有纪念意义的事情的时候,但是摄像完后把SD数据拷出来,却发现SD卡不能读取了,怎么办?相信,如果遇到这个问题的网友一定会急的像热锅上的蚂蚁。下面我们就来讨论下如果遇到这种问题了的解决办法。 先确认是SD卡的问题还是摄像机的问题。…

苹果电脑更改sd卡只读_SD内存卡禁止写入只读怎么办?另类SPI模式修复坏卡

这几天很郁闷,买的32G TF卡老出问题,三星的标,不知道是不是正品,标称C10,且不说是不是真的三星和真的C10,反正测试一下容量倒是真的,价格么也比较亲民,好像是69块? 哎,可惜呀,好景不长,坏了,变只读了。 这卡一直放老婆手机里用,上周突然手机不正常了,各种怪异…

适合手机运行的服务器系统,同样2GB内存 手机为啥不如电脑运行好?

电子设备流畅的运行,直接影响到用户的应用体验,应用体验是一个新兴的概念,但却是衡量电子设备优劣的一个重要指标,对电子产品的购买产生着直接的影响。 影响电子设备应用体验最直接因素就是硬件配置,相同的配置也有可能有不同的应用体验。在ZOL官方论坛中,就有多个网友提…

android+复制大文件,手机SD卡无法复制拷贝大文件的解决方法

现在的SD存储卡越来越便宜了,一个32G的价格在去年只能买到16G的,所以很多朋友都上了32G甚至更大的卡。但是很囧的情况发生了,这么大的存储卡居然不能复制大文件,相信很多朋友都碰到过这种囧事吧,还以为是SD卡的问题,其实吧,就是SD卡的问题,不过可能不是质量问题,而是它…

电脑tf卡检测不到_内存卡在电脑上读不出来怎么办 内存卡在电脑上读不出来解决方法【详细介绍】...

在如今科技产品众多的信息时代里,内存卡对于我们而言并不陌生。内存卡一般多用于手机、电脑、相机等产品上所能够独立存储的介质。不仅具有很好的兼容性,而且在不同的数码产品之间可以进行数据的交换。随着使用时间的增加,以及我们偶尔的操作不对加上内存卡本身的质量问题,…

root卡顿解决方法,手机root后很卡

手机root后屏卡顿 相机卡屏 系统更新出错,求解 楼主你好! 下面的流程是手机root后屏卡顿相机卡屏系统更新出错的解决方法! 1、如果用一些软件root之后已经造成了卡顿及掉相机问题,可以使用RE文件管理器先删除 /system/app 下的授权…

华为手机照片在电脑上显示计算机内存不足,关于华为荣耀手机提示内存不足的解决方法...

关于华为荣耀手机提示内存不足的解决方法 如果有条件或者可以升级的朋友,可以讲手机内存升级更大一些,目前主流手机内存已经达到了1GB,高端手机内存可达到2GB,对于高端手机一般由于手机内存较大,一般比较少出现手机内存…

youtube 视频下载

有几种方式可以下载 YouTube 视频: 使用第三方 YouTube 视频下载网站: 这种方式简单方便,但下载视频质量和格式受限,也可能涉及版权问题。常用的网站有: y2mate:https://y2mate.com/savefrom:https://www.savefrom.net/flvto:https://www.flvto.biz/ 在这些网站输入视频 URL …
最新文章