首页 » 网站推广 » phparray实现set技巧_ES6 数组 Array 集合 Set 运用

phparray实现set技巧_ES6 数组 Array 集合 Set 运用

访客 2024-12-19 0

扫一扫用手机浏览

文章目录 [+]

数组扩展

数组扩展运算符

phparray实现set技巧_ES6 数组 Array 集合 Set 运用

数组扩展运算符(spread)是三个点(...)。
它好比rest参数的逆运算,将一个数组转为用空格分隔的参数序列。

phparray实现set技巧_ES6 数组 Array 集合 Set 运用
(图片来自网络侵删)

console.log(...[1, 2, 3]); // 1 2 3console.log(1, ...[2, 3, 4], 5); // 1 2 3 4 5

⚠️rest参数是利用在函数参数上的,将函数参数转换为数组的形式,如下:

function fn(...values) { console.log(values); // ['jia', 'ming']}fn('jia', 'ming');

下面我们结合数组扩展运算符和rest参数来实现一个类似call的方法call2操作:

Function.prototype.call2 = function(context, ...args){ // 这里利用到rest参数context = context || window; // 由于通报过来的context有可能是nullcontext.fn = this; // 让fn的高下文为contextconst result = context.fn(...args); // 这里利用了数组扩展运算符delete context.fn;return result; // 由于有可能this函数会有返回值return}var job = 'outter teacher';var obj = {job: 'inner teacher'};function showJob() {console.log(this.job);}showJob(); // outter teachershowJob.call2(obj); // inner teacher

复习一下,我们把var job = 'outter teacher'改为let job = 'outter teacher'后,showJob()会输出什么?

答案是undefined。
在前一篇中也提到过,ES6语法声明的变量是不会挂载在全局工具上的~

Array.from()

Array.from方法用于将两类工具转为真正的数组:类似数组的工具(array-like object)和可遍历(iterable)的工具(工具包括ES6新增的数据构造Set和Map)。

// 类数组转化成数组let arrayLike = {'0': 'a','1': 'b','2': 'c',length: 3}// ES5的写法var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']// ES6的写法let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

Array.of()

Array.of()方法用于将一组值,转换为数组。

let arr = Array.of(2, 3, 'reng');console.log(arr); // [2, 3, 'reng']console.log(arr.pop()); // reng

Array.of基本上可以填补Array()或new Array()带来的由于参数个数导致的不同行为。
Array.of基本上可以替代它们两个了。

Array.of(); // []Array.of('reng'); // ['reng']Array.of(2, 'reng'); // [2, 'reng']

数组中还有其它有用的方法:

copyWithin(target, start = 0, end = this.length): 拷贝指天命组的范围值find(fn): 用于查找第一个符合条件的数组成员,没有返回undefinedfindIndex(fn): 用于查找第一个符合条件的数组成员的位置,没有返回-1entries(): 对键值对的遍历keys(): 对键的遍历values(): 对值的遍历includes(el): 返回一个布尔值,表示某个数组是否包含给定的值,与字符串的include(el)方法相似flat(num): 将嵌套的数组拉平,num是遍历的深度

[1, [2, [3]]].flat(Infinity);// [1, 2, 3]

有这么一个需求:将数组[[2, 8], [2], [[4, 6], 7, 6]]转成一维且元素不重复的数组。

我们的实现方案如下:

let arr = [[2, 8], [2], [[4, 6], 7, 6]];console.log([...new Set(arr.flat(Infinity))]); // [2, 8, 4, 6, 7]

工具扩展

属性名表达式

ES6许可字面量定义工具时,把表达式放在方括号内:

let lastWord = 'last word';const a = { 'first word': 'hello', [lastWord]: 'world', ['end'+'symbol']: '!' };a['first word'] // 'hello'a[lastWord] // 'world'a['last word'] // 'world'a['endsymbol'] // '!'

工具的扩展运算符

上面整理数组扩展内容的时候,提到了数组的扩展运算符。
ES2018将这个运算符引入了工具~

let z = { a: 3, b: 4 };let n = { ...z }; // 关键点n // { a: 3, b: 4 }

工具中某些新增的方法

Object.is(arg1, arg2): 比较两个值是否严格相等,与===行为基本同等Object.assign(target, source1, ...): 用于工具的合并,将源工具(source)的所有可列举属性,复制到目标工具(target)。
属于浅拷贝Object.keys(obj): 返回一个数组,成员是参数工具自身的(不含继续的)所有可遍历(enumerable)属性的键名Object.values(obj): 方法返回一个数组,成员是参数工具自身的(不含继续的)所有可遍历(enumerable)属性的键值。
Object.entries(obj): 方法返回一个数组,成员是参数工具自身的(不含继续的)所有可遍历(enumerable)属性的键值对数组。

const obj = { foo: 'bar', baz: 42 };Object.entries(obj)// [ [\公众foo\公众, \"大众bar\公众], [\公众baz\"大众, 42] ]

Set和Map数据构造

Set

Set翻译出来便是凑集,有元素唯一性的特点。

在数组去重的场景上很有用处:

// 去除数组的重复成员[...new Set(array)]// 如console.log([...new Set([2, 2, 3, 2])]); // [2, 3]

须要留神的Set属性和方法有以下:

size: 返回实例成员的总数add(value): 添加某个值,返回Set构造本身delete(value): 删除某个值,返回一个布尔值,表示删除是否成功。
has(value): 返回一个布尔值,表示该值是否为Set的成员clear(): 打消所有成员,没有返回值。
key():返回键名的遍历器。
values(): 返回键值的遍历器。
entries(): 返回键值对的遍历器。
forEach(): 利用回调函数遍历每个成员

WeakSet

WeakSet构造与Set类似,也是有不重复元素的凑集。
但是它和Set有两个差异:

WeakSet工具中只能存放工具引用, 不能存放值, 而Set工具都可以.WeakSet中工具中存储的工具值都是被弱引用的, 如果没有其他的变量或属性引用这个工具值, 则这个工具值会被当成垃圾回收掉. 正由于这样, WeakSet 工具是无法被列举的, 没有办法拿到它包含的所有元素。

var ws = new WeakSet();var obj = {};var foo = {};ws.add(window);ws.add(obj);ws.has(window); // truews.has(foo); // false, 工具 foo 并没有被添加进 ws 中 ws.delete(window); // 从凑集中删除 window 工具ws.has(window); // false, window 工具已经被删除了ws.clear(); // 清空全体 WeakSet 工具

WeakSet 没有size属性,没有办法遍历它的成员。

Map

Map工具保持键值对。
任何值(工具或者原始值)都可以作为一个键或一个值。

Object和Map的比较:

一个Object的键只能是字符串或者Symbols,但一个Map的键可以是任意值,包括函数、工具、基本类型。
Map中的键值是有序的,而添加到工具中的键则不是。
因此,当对它进行遍历时,Map工具是按插入的顺序返回键值。
Map在涉及频繁增删键值对的场景下会有些性能上风`。
...

如果你须要“键值对”的数据构造,Map比Object更得当。

const set = new Set([ // 数组转换为map ['foo', 1], ['bar', 2]]);const m1 = new Map(set);m1.get('foo') // 1const m2 = new Map([['baz', 3]]);const m3 = new Map(m2);m3.get('baz') // 3

Map拥有的属性和方法和Set相似,多出了些:

set(key, value):set方法设置键名key对应的键值为value,然后返回全体 Map 构造。
如果key已经有值,则键值会被更新,否则就新天生该键。
get(key):get方法读取key对应的键值,如果找不到key,返回undefined

WeakMap

WeakMap构造与Map构造类似,也是用于天生键值对的凑集。
但是有两点差异:

WeakMap只接管工具作为键名(null除外),不接管其他类型的值作为键名。
WeakMap的键名所指向的工具,不计入垃圾回收机制。
和WeakSet相似啦。

属性方法啥的跟Map差不多,便是没有了size和forEach,由于其是不可列举的。

Promise工具

Promise是异步编程的一种办理方案,比传统的办理方案“回调函数和事宜”更合理和更强大。

Promise工具有以下两个特点:

工具的状态不受外界影响。
Promise工具代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失落败)。
一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise工具的状态改变,只有两种情形:从pending变成fulfilled(fulfilled也称resolved)和从pending变成rejected。

用法

const promise = new Promise(function(resolve, reject) {// ...some codeif(/ 异步操作成功 /) {resolve(value);} else {reject(error);}})

参数resolve和reject是两个函数,由JavaScript引擎供应,不用自己支配。

Promise实例天生之后,可以利用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {// success}, function(error) {// failure});

我们来粘贴个大略例子:

function timeout(ms) {return new Promise((resolve, reject) => {setTimeout(resolve, ms, 'done');});}timeout(100).then((value) => {console.log(value); // 100ms后输出'done'});

嗯~我们顺道来复习下setTimeout的第三个参数。
哦,不,是第三个,第四个...

var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]);function 是你想要在到期韶光(delay毫秒)之后实行的函数。
delay 是可选语法,表示延迟的毫秒数。
param1, ..., paramN 是可选的附加参数,一旦定时器到期,它们会作为参数通报给function

那么,到这里你理解了上面的例子为什么在100ms后输出done了嘛

详细的setTimeout信息,请戳MDN的setTimeout。

大略的例子看完了,看下我们在事情中利用得比较多的要求接口的例子:

const getJSON = function(url) {const promise = new Promise(function(resolve, reject){const handler = function() {if(this.readyState !== 4) {return;}if(this.status === 200) {resolve(this.response); // this.response作为参数传给then中的json} else {reject(new Error(this.statusText));}};const client = new XMLHttpRequest();client.open('GET', url);client.onreadystatechange = handler;client.responseType = 'json';client.setRequestHeader('Accept', 'application.json');client.send();});return promise;};getJSON('/post.json').then(function(json) {console.log('Contents: '+ json);}, function(error) {console.log('error happen ', error);});

catch方法

Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生缺点时的回调函数。

p.then((val) => console.log('fulfilled:', val)).catch((err) => console.log('rejected', err)); // promise中任何一个抛出错误,都会被末了一个catch捕获// 等同于p.then((val) => console.log('fulfilled:', val)).then(null, (err) => console.log('rejected:', err));

finally方法

Promise.prototype.finally()方法(其不接管任何参数)用于指定不管Promise工具末了状态如何,都会实行的操作。
该方法是 ES2018 引入标准的。

语法:

promise.then(result => {···}).catch(error => {···}).finally(() => {···});

Promise.all

布局函数方法Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。

const p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all方法接管一个数组作为参数,p1, p2, p3都是Promise实例。
如果不是会调用Promise.resolve方法,详细看文档。

// 天生一个Promise工具的数组const promises = [2, 3, 5, 7, 11, 13].map(function (id) {return getJSON('/post/' + id + \"大众.json\公众);});Promise.all(promises).then(function (posts) {// ...}).catch(function(reason){// ...});

上面代码中,promises是包含 6 个 Promise 实例的数组,只有这6个实例的状态都变成fulfilled,或者个中有一个变为rejected,才会调用Promise.all方法后面的回调函数。

⚠️把稳,如果作为参数的Promise实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
以是利用Promise.all()别手痒在每个实例promise内添加缺点捕获。

一道练手题

需求:利用promise改写下面的代码,使得输出的期望结果是每隔一秒输出0, 1, 2, 3, 4, 5,个中i < 5条件不能变

for(var i = 0 ; i < 5; i++){ setTimeout(function(){ console.log(i); },1000)}console.log(i);

我们直接上利用promise改写的代码吧~

const tasks = []; // 存放promise工具for(let i = 0; i < 5; i++){tasks.push(new Promise((resolve) => {setTimeout(() => {console.log(i);resolve();}, 1000 i);}));}Promise.all(tasks).then(() => {setTimeout(() => {console.log(tasks.length);}, 1000);});// 每隔一秒输出 0, 1, 2, 3, 4, 5

标签:

相关文章

php常量率低技巧_PHP 常量详解教程

PHP 常量常量是单个值的标识符(名称)。在脚本中无法改变该值。有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号)。注释...

网站推广 2024-12-19 阅读0 评论0