第10章 Arrays & TypedArrays

Arrays

ES6对数组添加了一些新的方法,另外还添加了TypedArray类型,这种类型支持对内存的操作,ArrayBuffer和C语言内存分配一样,分配一块内存块。下面从以下几个方面来看看ES6数组的变化:

  1. 2个静态方法 Array.of(), Array.from();
  2. 数组原型上新添加的方法 find(), findIndex(), fill(), copyWithin();
  3. 新类型 ArrayBuffer;
  4. Typed Arrays, 以及和Array的相同性,差异性

一.Array.of() & Array.from()

1.Array.of()

ES6新添加了这个静态方法,用于数组构造器实例化数组。我们知道数组实例化一般可以通过构造器或者数组字面量的形式来声明。ES5通过构造器声明数组会出现一个比较模糊的地方,比如:

var arr = new Array(1, 2, 3);
// 表示声明一个数组元素为[1, 2, 3]的数组
arr.length; // 3
arr[0]; // 1
arr[1]; // 2
arr[2]; // 3

var arr = new Array(2); // 2表示长度
// 而这样则表示一个数组长度为2的数组,而数组元素未声明
arr.length; // 2
arr; // [undefined, undefined]

Array.of()消除了这种模糊,凡是向方法中添加数字,都表示数组元素,而不是长度

var arr = Array.of(1, 2);
arr; // [1, 2]

var arr = Array.of(2); // 2表示元素
arr; // [2]

2.Array.from()

ES6之前要将一个array-like对象转换成数组,我们一般是利用slice方法,比如

function doSomething() {

    // 将arguments类数组对象转换成数组
    var args = Array.prototype.slice.call(arguments);
    // 或者  [].slice.call(arguments)
    // ...

}

ES6通过静态方法 Array.from() 可以将 类数组对象 或者 可迭代的对象 转换成一个数组,其语法为:

Array.from(arraylike[, callback] [, thisArg])

上面的例子可以写为:

function doSomething() {
    var args = Array.from(arguments);
    // ...
}

将可迭代的对象转变为数组:

var set = new Set([1, 2, 2, 4, 5]);
// Set {1, 2, 4, 5}
var arr = Array.from(set); // [1, 2, 4, 5]

后面添加回调函数, 如果回调函数属于一个对象, 则可以添加第3个可选参数,指出this上下文:

let helper = {
    diff: 1,
    add(value) {
        return value + this.diff;
    }
}
 
function translate() {
    // 第2个参数为callback, 第3个参数为上下文
    return Array.from(arguments, helper.add, helper);
}

translate(1, 2, 3); // [2, 3, 4]

二.新添加的方法

1.find(),findIndex()

以前我们查看数组中是否存在某个值或者某个值的位置时,一般使用indexOf(), lastIndexOf(),ES6添加了find(), findIndex()来添加条件查找。这两个方法和map(),forEach()一样添加一个回调函数,有选择性的添加thisArg指定上下文。

find找到了就返回第一个满足条件的,未找到返回undefined, findIndex返回索引位置,未找到返回 -1:

var arr = [1, 2, 19, 16];
arr.find(v => v > 10 );  // 返回 19
arr.findIndex(v => v > 10); // 返回 2

find(), findIndex()用于查找一个数组元素满足某个条件而不是值,要根据值查找建议使用indexOf(), lastIndexOf().

2.fill(), copyWithin()

这两个方法其实为了操作Typed Array对象使用的,但是为了保持一致性,也添加给普通数组了。看下语法:

  1. fill(value[,startFillPostion = 0 ] [, endFillPostion = arr.length])
  2. copyWithin(StartToBeCopiedPos[,StartCopyPos = 0] [,EndCopyPos = arr.length])

先看fill:

var arr = [1, 2, 3, 4];

// 不指定开始和结束填充的位置
arr.fill(5); // arr: [5, 5, 5, 5]

// 指定开始
arr.fill(5, 2); // arr: [1, 2, 5, 5]

// 都指定,不包含结束位置
arr.fill(5, 0, 2)// arr: [5, 5, 3, 4]

// 当然起始和结尾也可以为负数,相当于加上数组长度
arr.fill(5, -3); // arr: [1, 5, 5, 5]
// 相当于 arr.fill(5, -3+4)

copyWith: 比较绕, 它是指复制自身内容到指定的位置:

var arr = [1, 10, 15, 29, 18];

// 只有一个参数表示被复制的索引,另外2个参数则默认从0开始到结束
arr.copyWithin(2); // arr [1, 10, 1, 10, 15]

// 2个参数,指定自身复制的位置
arr.copyWithin(3, 1); // arr [1, 10, 15, 10, 15]

// 3个参数都指定
arr.copyWithin(2, 0, 1); // arr [1, 10, 1, 29, 18]
// 0-1只有一个数 "1", 所有索引位置为2的 "15" 被替换成 "1"

上面例子我们可以发现,是有这些方法都会改变数组自身


三.ArrayBuffer

AarryBuffer是指分配内存中的一块位置用于操作,相当于C语言中的malloc(),对内存块进行二进制操作,会极大的提升性能,满足一些特别的接口要求。
先了解一下内存分配的基本语法:

var buffer = new ArrayBuffer(bytes);

比如:分配10个字节(byte)

var buffer = new ArrayBuffer(10);

内存的大小确定之后是不能修改的,可以改变内部内容

属性: byteLength , slice()
slice方法是从已经存在的内存块中复制一段,添加都新的内存块中

var buffer = new ArrayBuffer(10);
var buffer2 = buffer.slice(3, 5);
// 将buffer中的3, 4字节内容拷贝到新的内存块中
 console.log(buffer2.byteLength); // 2

四.TypedArray, Views视图

光有内存块,而不进行操作也是没有用的,javascript通过视图的方式对内存块进行读写,存在两种视图:

  1. TypedArray: 特定类型的数据类型,特定类型的一种视图,对特定类型操作性能更高;
  2. DataView: 各种数据类型都可以,还可以指定大端序(BIG_ENDIAN),小端序(LITTLE_ENDIAN),功能更强大的一种视图

1.共同属性

这两种视图拥有一些共同的属性:

  • buffer: 表示指向的内存块;

2.DataView

DataView构造器能够添加三个参数:new DataView(buffer[, byteOffset][, byteLength])

var buffer = new ArrayBuffer(10);
// 指向整个内存块
var dataView1 = new DataView(buffer);    
dataView1.buffer === buffer; // true
dataView1.byteOffset; // 0
dataView1.byteLength; // 10

// 表示 字节 5, 6上的视图
var dataView2 = new DataView(buffer, 5, 2);
dataView2.buffer === buffer; // true
dataView2.byteOffset; // 5
dataView2.byteLength; // 2

3.TypedArray

TypedArray本质上是一个抽象类,他表示9中特定类型: Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array,
Float64Array,还有一种只针对Canvas颜色值的 Uint8ClampedArray

具体使用方法参见阮一峰大神的博客: 二进制数组


总结

总的来说,ES6数组的变化还是很大的,新添加的方法和类型使得数组更加的强大,TypedArray,ArrayBuffer,DataView等API的添加对一些需要二进制操作的接口提供了原生的支持,像canvas, webGL, file, websocket等,这些还需再日后的使用中总结提炼。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容