Day 28 [整理03] JavaScript类数组

甚麽是类数组

先来打造一个很酷的数组

let obj = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  'length': 3,
  'push': Array.prototype.push
}
console.log(obj);

https://ithelp.ithome.com.tw/upload/images/20210201/20124350YgW9pNEjWB.png

乍看之下他还只是一个平常的对象,但其实这个对象这时候已经变成一个类数组了!

我们来对他做以下操作可以更明白

https://ithelp.ithome.com.tw/upload/images/20210201/20124350nuCIVlxBK7.png

可以发现到这时候他多了一个 3: "d" ,对象原本是不能这样做的,但是在这边却可以实现,因此才对他取名叫做类数组。

如何打造

要打造出一个类数组有几个条件

  1. 他必须要是一个对象
  2. 属性要为索引(数字)值
  3. 一定要有length存在
  4. 最好可以加push

附注:

如果想让它变得更像数组可以加上splice,如下图

https://ithelp.ithome.com.tw/upload/images/20210201/20124350AXpzr50iPi.png

来一个比较难问题

let obj = {
  '2': 'c',
  '3': 'd',
  'length': 3,
  'push': Array.prototype.push,
};

obj.push('f')
obj.push('g')

console.log(obj);

大家先别看答案,先想想看这个东西打印出来会长怎样

答案

https://ithelp.ithome.com.tw/upload/images/20210201/20124350L0C2c0A6s6.png

分析

3的 "d" 居然被 "f" 覆盖掉了,而且多了一个4 : "g" ,我们来讲解一下实现原理!!

先来看看 Array.prototype.push 源码

撷取自

https://www.jianshu.com/p/85d1ec72a140

function ArrayPush () {
  var n = TO_UNIT32(this.length); // 被push数组的长度(类数组采用的length就是这个!)
  var m = %_ArgumentsLength(); // push的总长度
  for (var i = 0; i < m; i++) {
    this[i + n ] = %_Arguments(i); // 复制给原数组
  }
  this.length = n + m; // 修正最终数组长度
  return this.length;
}

从第2行可以得知为甚麽Obj一定要有length

再来第4到6行就能知道他push的观点全是在length上

也就是说在obj对象最该观察的不是其他元素而是length!

再来看看原题目

let obj = {
  '2': 'c',
  '3': 'd',
  'length': 3,
  'push': Array.prototype.push,
};

obj.push('f')
obj.push('g')

console.log(obj);

到这边就很明了为甚麽 3会变f 而 4会变g,原因全在

https://ithelp.ithome.com.tw/upload/images/20210201/20124350oRFEw1lNdT.png

思路

​ 大家可以想一下i = 0 的情况下会发生甚麽事,是不是this[0 + n]会被push的第一个元素取代,那这里他的n代表的不就是Obj的 length

​ 就表示说Obj [3] 会被 f 取代,并且length变4 ,然後Obj[4]再被 g取代,length变5!这就是这题的实现原理。


<<:  Day 27 [其他05] 前端必知必会--操作URL的黑科技

>>:  Day 30 [分享] 学习 JavaScript 的优秀资源

【Day20】电子商务与行销篇-UTMs

#odoo #开源系统 #数位赋能 #E化自主 UTMs对行销人来说算是非常熟悉的工具,不光只是缩短...

Day 19 : KNN 与 K-means

今天进入演算法的介绍,首先打头阵介绍的是 KNN 与 K-means,两者不太一样。 KNN 是监督...

Logback 配置来客制化 Log 讯息吧

在 Spring boot 可以使用 Logback 进行配置,系统预设加载日志配置档案 logba...

大共享时代系列_009_共享农场

有没有想过除了从菜市场、超级市场买菜以外,试着跟人在离家不远的农场,共享农作、畜牧来获取需求的天然的...

Day 11:「动起来!动起来!」- 用 Tailwind 简单做出过渡和动画效果

还记得我们在之前做过变化模式吗? 没错,就是滑鼠悬停之後会变色的那个。 我们今天呢,就是要来帮它们...