深入理解es6之《改进的数组功能》(代码片段)

jlfw jlfw     2022-12-04     626

关键词:

Array.of方法

由于Array构造函数创建数组时的怪异行为,比方说如下:

let items = new Array(2)
console.log(items.length)//2
items = new Array("2")
console.log(items.length)//1

Array.of方法总会创建一个包含所有参数的数组

let items = Array.of(1, 2)
console.log(items.length)//2
console.log(items[0])//1

Array.of方法不通过Symbol.species属性确定返回值的类型,它使用当前构造函数,也就是of方法中的this值来确定正确的返回数据的类型

Array.from方法

以前总是使用Array.prototype.slice.call(arrayLike)将类数组转换成数组
Array.from方法可接受可迭代对象或类数组对象,最终返回一个数组
Array.from也是通过this来确定返回数组的类型
Array.from接受第二个参数,表示映射函数,第三个参数表示映射函数中的this的值
来看几个例子:

function translate() 
    return Array.from(arguments, (value) => value + 1)

let numbers = translate(1, 2, 3)
console.log(numbers) //2、3、4
let helper=
    diff:1,
    add(value)
        return value+this.diff
    

function translate()
    return Array.from(arguments,helper.add,helper)

let numbers = translate(1, 2, 3)
console.log(numbers) //2、3、4

看看用Array.from转换可迭代对象

let numbers = 
    *[Symbol.iterator]() 
        yield 1;
        yield 2;
        yield 3;
    

let numbers2 = Array.from(numbers, value => value + 1)
console.log(numbers2) //2、3、4

find方法和findIndex方法

find方法和findIndex方法都接受两个参数,一个是回调函数,另外一个是可靠参数用于指定回调函数中this的值


let numbers = [25, 30, 35, 40, 45]
console.log(numbers.find(n => n > 35))//40
console.log(numbers.findIndex(n => n > 35))//3

如果要在数组中根据某个条件查找匹配的元素,那么find方法和findIndex方法可以很好的完成任务,但是如果只想查找与某个值匹配的元素,则indexOf和lastIndexOf应该是更好的选择

fill方法

fill方法可以用指定的值填充一至多个数组元素,当传入一个值时,fill方法会用这个值重写数组中的所有值
fill方法的第二个参数表示开始索引,第三个参数作为不包含结束索引,如果没有传第三个参数则默认使用numbers.length作为不包含结束索引
如果开始索引和结束索引为负值,那么这些值会与数组的length属性相加为作为最终位置

copyWithin方法

调用copyWithin方法时需要传入两个参数,一个是方法开始填充值的索引位置,另一个是开始复制值的索引位置,第三个参数为可选参数,用来限制被重写元素的数量,也就是指定停止复制值的位置

let numbers = [1, 2, 3, 4]
numbers.copyWithin(2, 0, 1)
console.log(numbers)//1,2,1,4

跟fill方法一样,copyWithin方法的所有参数都接受负数值,并且会自动与数组长度相加来作为最终使用的索引

定型数组

JS中数字是以64位浮点格式存储并按需转换成32位整数
数组缓冲区是所有定型数组的根基,数组缓冲区包含的实际字节数量在创建时就已确定,可以修改缓冲区内的数据,但是不能修改缓冲区的尺寸大小

let buffer = new ArrayBuffer(10)
let buffer2 = buffer.slice(4, 6)
console.log(buffer2.byteLength)//2

数组缓冲区是内存中的一段地址,视图是用来操作内存的接口,视图可以操作数组缓冲区或缓冲区字节的子集,并按照其中一种数值型数据类型来读取和写入数据

let buffer = new ArrayBuffer(10),
    view1 = new DataView(buffer),
    view2 = new DataView(buffer, 5, 2);
console.log(view1.buffer === buffer)//true
console.log(view2.byteOffset)//5
console.log(view2.byteLength)//2

事实上你可以写入两个int8类型的值,然后使用int16类型的方法从缓冲区中读出这些值

let buffer = new ArrayBuffer(10),
    view = new DataView(buffer);
view.setInt8(0, 5)
view.setInt8(1, -1)
console.log(view.getInt8(0))//5

定型数组实际上就是用于数组缓冲区的特定类型的视图,你可以强制使用特定的数据类型,而不是通过使用通用的DataView对象来操作数组缓冲区
创建定型数组的方式

1、 通过数组缓冲区来生成定型数组的实例

let buffer = new ArrayBuffer(10),
    view = new Int8Array(buffer);
console.log(view.byteLength)

2、通过构造函数中传入一个数字,这个数字表示分配给数组的元素数量

let ints = new Int32Array(10);
console.log(ints.byteLength)//20
console.log(ints.length)//10

调用定型数组的构造函数时如果不传参数,会按照传入0来处理,这样由于缓冲区没有分配到任何比特,因为创建的定型数组不能用来保存数据

  1. 可以将定型数组、可迭代对象、数组、类数组对象作为构造函数的参数传入
let ints1 = new Int16Array([25, 50]),
    ints2 = new Int32Array(ints1);
console.log(ints1.buffer === ints2.buffer)//false
console.log(ints1.length)//2
console.log(ints2.byteLength)//8
console.log(ints2.length)//2
console.log(ints2[0])//25
console.log(ints2[1])//50

每个定型数组中元素大小指的是每个元素表示的字节数,该值存储在每个构造函数和每个实例中BYTES_PER_ELEMENT属性中

console.log(Uint32Array.BYTES_PER_ELEMENT)

定型数组和普通数组的异同点

相同点:
1、可以修改length属性来改变普通数组的大小,而定型数组的length属性是一个不可写属性,所以不能修改定型数组的大小,如果尝试修改这个值,在非严格模式下会直接忽略该操作,在严格模式下会抛出错误
2、定型数组也包括许多在功能上与普通数组方法等效的方法,但是定型数组中的方法会额外的检查数值类型是否安全
比方说:copyWithin、findIndex、lastIndexOf、slice、entries、forEach、map、some、fill、indexOf、reduce、sort、filter、join、reduceRight、values、find、keys、reverse
3、相同的迭代器(也就是keys、values、entries),这意味着可以把定型数组当作普通数组一样来使用展开运算符、for of 循环

let ints = new Int16Array([25, 50]),
    intsArray = [...ints];
console.log(intsArray instanceof Array)//true
console.log(intsArray[0])//25

4、所有定型数组都包含有静态of方法和from方法(也就是Array.of和Array.from)
差异点:
1、定型数组不是普通数组,它不继承自Array,通过Array.isArray方法检测定型数组返回的是false


let ints = new Int16Array([25, 50])
console.log(ints instanceof Array)//false
console.log(Array.isArray(ints))//false

2、当操作普通数组时,其可以变大变小,但定型数组却始终保持相同的尺寸。给定型数组中不存在的数值索引赋值会被忽略,而在普通数组中就可以

let ints = new Int16Array([25, 50]);
console.log(ints.length);//2
console.log(ints[0])//25
console.log(ints[1])//50
ints[2]=5;
console.log(ints.length)//2
console.log(ints[2])//undefined

定型数组同样会检查数据类型的合法性,0被用于代替所有非法值;所有修改定型数组值的就去执行时都会受到相同限制

let ints = new Int16Array([‘hi‘])
console.log(ints.length)//1
console.log(ints[0])//0

3、以下方法在定型数组中不可使用,concat、shift、pop、splice、push、unshift
因为上述列表中除concat外,所有方法都可以改变数组的尺寸,由于定型数组的尺寸不可更改,因而这些方法不适用于定型数组,之所以concat不行是因为两个定型数组合并后的结果会变得不确定
4、定型数组新的附加方法set和subarray
set方法将其它数组复制到已有的定型数组
subarray提取已有定型数组的一部分作为一个新的定型数组

set方法接受两个参数:一个是数组(定型数组或普通数组都支持),一个是可选的偏移量,表示开始插入数据的位置,如果什么都不传,默认的偏移量是0

let ints = new Int16Array(4);
ints.set([25, 50])
ints.set([75, 100], 2)
console.log(ints)//[25, 50, 75, 100]

subarray方法接受两个参数:一个是可选的开始位置,一个是可选的结束位置(不包含当前结束位置的值 ),最后返回一个新的定型数组,也可以省略这两个参数来克隆一个新的定型数组

let ints = new Int16Array([25, 50, 75, 100]),
    subInts = ints.subarray(1, 3);
console.log(subInts)//[50, 75]

本文转载于:猿2048深入理解ES6之《改进的数组功能》



















《深入理解es6》之扩展对象的功能性

 属性初始值的简写  当一个对象的属性与本地变量同名时,不必再写冒号和值,简单地只写属性名即可。functioncreatePerson(name,age){return{name,age};}//相当于functioncreatePerson(name,age){return{name:name,age:age};}对象方法的简写  ES6中... 查看详情

深入理解es6之《代理和反射》(代码片段)

使用set陷阱验证属性lettarget=name:‘target‘letproxy=newProxy(target,/*****@paramanytrapTarget用于接收属性(代理的目标)的对象*@paramanykey要写入的属性键*@paramanyvalue被写入的属性的值*@paramanyreceiver操作发生的对象(通常是代理)*/set(trapTarg 查看详情

深入理解es6之《函数》(代码片段)

默认参数ES5中要为参数指定默认值,只能如下所示:functionmakeRequst(url,timeout,callback)timeout=timeout||2000;callback=callback||function()但是这样有一个问题如果timeout传进来的值为0,则也会赋值变成2000,所以更加完全的做法是检测参数类型fu... 查看详情

深入理解es6之《es6中较小的改动》(代码片段)

识别整数console.log(Number.isInteger(25))//trueconsole.log(Number.isInteger(25.0))//trueconsole.log(Number.isInteger(25.1))//false安全整数IEEE754只能准确的表示-2的53次方到2的53次方的整数letinside=Number.MAX_SAFE_INTEGER,outsi 查看详情

深入理解es6之《用模块封装代码》(代码片段)

什么是模块模块是自动运行在严格模式下并且没有办法退出运行的Javascript代码在模块的顶部this的值是undefined其模块不支持html风格的代码注释除非用default关键字,否则不能用这个语法导出匿名函数或类任何未显示导出的变量、... 查看详情

《深入理解es6》之symbol

  ES6在原有的5中原始类型:字符串、数字型、布尔型、null和undefined的基础上,引入了一种原始类型Symbol(可以通过typeof检测变量是否为Symbol类型)。Symbol的使用方法  所有使用可计算属性名的地方,都可以使用Symbol。letfirstN... 查看详情

《深入理解es6》之解构

结构是一种打破数据解构,将其拆分为更小部分的过程。对象解构  对象字面量的语法形式是在一个赋值操作符左边放置一个对象字面量。letnode={type:"indefine",name:"foo"};let{type,name}=node;console.log(type);//indefineconsole.log(type);//foo解构... 查看详情

es6系列_3之变量的解构赋值(代码片段)

...)对变量赋值。(2)数组模式和赋值模式统一可以简单的理解为等号左边和 查看详情

es6之数组(代码片段)

数组新增方法map(可以理解为是映射,以一定规则修改数组每一项并返回全新数组)reduce(可以理解为是汇总,一堆出来一个)filter(可以理解为过滤,筛选的意思,以一定规则拿到符合的项并返回新数组)forEach(感觉和for循... 查看详情

深入理解es6箭头函数中的this(代码片段)

简要介绍:箭头函数中的this,指向与一般function定义的函数不同,比较容易绕晕,箭头函数this的定义:箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定。 1、何为定义时绑定我们来看下面这个例子:... 查看详情

pandas之:深入理解pandas的数据结构(代码片段)

目录简介Series从ndarray创建从dict创建从标量创建Series和ndarraySeries和dict矢量化操作和标签对齐Name属性DataFrame从Series创建从ndarrays和lists创建从结构化数组创建从字典list创建从元组中创建列选择,添加和删除简介本文将会讲解Pandas... 查看详情

总结学习springcloud系列之深入理解zuul(代码片段)

简介网关(gateway)是一种外部网络和内部网络服务之间的关卡,可以最先得到外部的请求,属于软件网卡。软件网卡主要有两个作用,一个是请求过滤,另一个是路由分发特点功能身份验证校验和安全限流动态路由... 查看详情

总结学习springcloud系列之深入理解zuul(代码片段)

简介网关(gateway)是一种外部网络和内部网络服务之间的关卡,可以最先得到外部的请求,属于软件网卡。软件网卡主要有两个作用,一个是请求过滤,另一个是路由分发特点功能身份验证校验和安全限流动态路由... 查看详情

es6之解构赋值(代码片段)

...可以将值从数组或属性从对象提取到不同的变量中。如果理解起来感觉抽象,直接看下面例子:数组解构:我们在以前要给变量赋值需要像下面这样写:vararr=[1,2.3];vara=arr[0];varb=arr[1];varc=arr[2];是不是感觉略繁琐了点?而如果我们... 查看详情

对springaop的进一步深入理解(代码片段)

前言从AOP的开启,到切面生成,再到代理类注入,最后增强方法的调用整个流程做一个整理和理解。将SpringAOP功能整体串联起来。@EnableAspectJAutoProxy开启AOP功能前面已经研究过这个注解原理:Spring之@EnableAspec... 查看详情

深入浅出的webpack构建工具---babel之配置文件.babelrc(代码片段)

阅读目录一:理解babel之配置文件.babelrc基本配置项二:在webpack中配置babel回到顶部一:理解babel之配置文件.babelrc基本配置项1.什么是babel?它是干什么用的?  ES6是2015年发布的下一代javascript语言标准,它引入了新的语法和... 查看详情

es6知识盲点整理(代码片段)

...通函数和箭头函数中this的指向问题call、apply和bind的区别深入理解ES6箭头函数里的thisES6(...)展开运算符箭头函数箭头函数JS数组的map()方法map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回... 查看详情

深入理解es6之——迭代器与生成器

迭代器迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都有next方法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时表示没有更多对值可供使用... 查看详情