【JavaScript 漫游】【006】数据类型 array

海景_桥梁
文章简介

本文为【JavaScript 漫游】专栏的第 006 篇文章,记录笔者在了解 JS 数据类型 array 中摘录的知识点。

  1. 数组的本质是对象
  2. 属组的 length 属性
  3. for ... in 循环和数组的遍历
  4. 数组的空位
  5. 类数组对象

除了上述 5 个重要知识点,学习数组更为重要的是掌握它的静态方法和实例方法,笔者计划再后面单独写一篇文章进行总结。

数组本质上是一种特殊的对象

typeof 运算符返回数据的数据类型是 object,这说明在本质上,数组属于一种特殊的对象。而它的特殊性体现在,它的键名是按次序排列的一组整数。

var arr = ['a', 'b', 'c'];
Object.keys(arr);  // ['0', '1', '2']

length 属性

数组的 length 属性,返回数组的成员数量。

['a', 'b', 'c'].length;  // 3

只要是数组,就一定有 length 属性。该属性是一个动态的值,等于键名中的最大整数加上 1。要注意的是,数组的数字键不需要连续,length 属性的值总是比最大的那个整数键大 1

var arr = ['a', 'b'];
arr.length // 2

arr[2] = 'c';
arr.length // 3

arr[9] = 'd';
arr.length // 10

arr[1000] = 'e';
arr.length // 1001

length 属性是可写的,如果人为设置一个小于当前成员个数的值,该数组的成员数量会自动减少到 length 设置的值。如果将 length 属性设为 0,就可以清空数组。如果设的值不合法,比如 -1,JS 会报错。

var arr = [ 'a', 'b', 'c' ];
arr.length // 3

arr.length = 2;
arr // ["a", "b"]

arr.length = 0;
arr // []

for...in 循环和数组的遍历

既然数组是一种特殊的对象,那么 in 运算符和for...in循环同样能作用到数组上。

in 运算符检查某个键名是否存在。

var arr = [];
arr[100] = 'hello';
1 in arr;  // false
100 in arr;  // true

for...in循环可以遍历数组的所有键名。特别注意的是,它不仅会遍历数组的数组键,也会遍历非数组键。终究是因为数组本质是一种对象,它的标准键名是数值,但如果人为赋予字符串键名是没有问题的。

var arr = ['a', 'b', 'c'];
arr['hello'] = 'world';
arr.length; // 3
for (var key in arr) {
  console.log(key);
}
// 0
// 1
// 2
// hello

基于 for...in 循环会遍历到非数组键,所以,遍历数组的时候最好不要用for...in,转而使用for循环或while循环更好。

笔者认为,遍历对象使用 Object.keys 方法,遍历数组使用for循环以及数组的实例方法forEach是最好的,工作遍历数组时使用forEach方法比for循环的频率更高。

数组的空位

当数组的某个位置是空元素,就称该数组存在空位。

var arr = [1, , 1];
a.length;  // 3
a[1];  // undefined

数组的某个位置是空位,与某个位置是 undefined,是不一样的。如果是空位,使用数组的 forEach 方法、for...in 结构、以及Object.keys 方法进行遍历,空位都会被跳过。而由于空位的存在对 length 属性没有影响,使用 length 属性配合 for 循环遍历数组的时候,要确保数组没有空位。

var arr = [1, , 1];
arr.forEach(function(value, index) {
  console.log('arr[' + index + '] = ' + value);
})
// arr[0] = 1
// arr[2] = 1

for (var key in arr) {
  console.log('arr[' + key + '] = ' + arr[key]);
}
// arr[0] = 1
// arr[2] = 1

Object.keys(arr); // ['0', '2']

for (var i = 0; i < arr.length; i++) {
  console.log('arr[' + i + '] = ' + arr[i]);
}
// arr[0] = 1
// arr[1] = undefined,值为 undefined 在实际开发过程会诱发报错
// arr[2] = 1
var arr = [1, undefined, 1];
arr.forEach(function(value, index) {
  console.log('arr[' + index + '] = ' + value);
})
// arr[0] = 1
// arr[1] = undefined
// arr[2] = 1

for (var key in arr) {
  console.log('arr[' + key + '] = ' + arr[key]);
}
// arr[0] = 1
// arr[1] = undefined
// arr[2] = 1

Object.keys(arr); // ['0', '1', '2']

for (var i = 0; i < arr.length; i++) {
  console.log('arr[' + i + '] = ' + arr[i]);
}
// arr[0] = 1
// arr[1] = undefined
// arr[2] = 1

由此可知,遍历数组的最好方法就是 forEach

简单总结,空位就是数组没有这个元素,所以不会被遍历到,而 undefined 表示数组有这个元素,值是 undefined ,所以遍历不会跳过。

类数组对象

如果一个对象的所有键名都是正整数或零,并且有 length 属性,那么这个对象就很像数组,语法上称为 类数组对象

var obj = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};
obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function

类数组对象并不是数组,因为它们不具备数组特有的方法,它们的根本特征是有 length 属性,只要有 length 属性,就可以认为这个对象类似于数组。但是有一个问题,这种 length 属性不是动态值,不会随着成员的变化而变化。

var obj = {
  length: 0
};
obj[3] = 'd';
obj.length // 0

典型的类数组对象是函数的 arguments 对象,以及大多数 DOM 运算集,还有字符串。

数组的 slice 方法可以将类数组对象变成真正的数组。

var str = 'hello';
var arr = Array.prototype.slice.call(str);

除了转为真正的数组,类数组对象还有一个办法可以使用数组的方法,就是通过 call 方法将数组的方法放到对象上。

function print(value, index) {
  console.log(index + ' : ' + value);
}
var str = 'hello';
Array.prototype.forEach.call(str, print);

要注意的是,使用 call 方法调用 forEach 这种方式,比直接使用数组原生的 forEach 方法要慢,所以最好先将类数组对象转为真正的数组,然后再直接调用数组的 forEach 方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/370059.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSS transition(过渡效果)详解并附带示例

CSS过渡效果&#xff08;CSS transitions&#xff09;是一种在元素属性值发生变化时&#xff0c;通过指定过渡效果来实现平滑的动画效果的方法。通过定义起始状态和结束状态之间的过渡属性&#xff0c;可以使元素的变化更加流畅和可视化。 过渡效果的基本语法如下&#xff1a;…

使用潜在向量进行检测、屏蔽和重建以进行遮挡的面部表情识别

Latent-OFER: Detect, Mask, and Reconstruct with Latent Vectors for Occluded Facial Expression Recognition 一、创新点 &#xff08;1&#xff09;提出了一种与表情相关的特征提取器&#xff0c;它使用空间注意力为特定的面部特征分配更高的权重&#xff0c;从而使我们能…

前端开发中不同语言【react-i18next】

目录 查看并设置语言 单页面&#xff1a;html lang ​编辑 浏览器 自定义翻译&#xff1a;react-i18next 设置 模块&#xff1a;staticData.ts 散(重复利用)&#xff1a;命名空间.json 应用 准备 html标签 查看并设置语言 单页面&#xff1a;html lang 英语: <…

RflySim | 定点位置控制器设计实验三

RflySim| 定点位置控制器设计实验三 01 分析实验 1.调节PD控制器的相关参数改善系统控制性能&#xff0c;并记录超调量和调节时间&#xff0c;得到满意的参数。 2.在得到满意参数后&#xff0c;对系统进行扫频以绘制Bod图&#xff0c;观察系统幅频响应、相频响应曲线&#xf…

【服务器】RAID(独立磁盘冗余阵列)

RAID&#xff08;独立磁盘冗余阵列&#xff09; 一、RAID的介绍二、RAID的分类#2-1 RAID 02-2 RAID 1#2-3 RAID 32-4 RAID 52-5 RAID 62-6 RAID 10(先做镜像&#xff0c;再做条带化)2-7 RAID 01&#xff08;先做条带&#xff0c;再做镜像&#xff09;2-8 RAID比较 三、磁盘阵列…

国内最全的Spring Boot系列之七

• 阿里巴巴前高级研发工程师 • 三家千万级互联网企业技术顾问 • MBTI/盖洛普技术专家 • 厦门某高校外聘教师 • 51CTO特约合作讲师 • 网易云课堂签约讲师 •《深入理解设计模式》作者 一转眼马上要过年了&#xff0c;回首2023年&#xff0c;感觉自己无所事事、碌碌无…

探索网络定位与连接:域名和端口的关键角色

目录 域名 域名的作用 域名的结构 域名的解析配置 父域名、子域名​编辑 https的作用 端口 图解端口 端口怎么用 判断网站是否存活 端口的作用 域名 域名是互联网上用于标识网站的一种易于记忆的地址。 域名是互联网基础架构的一个重要组成部分&#xff0c;它为网…

Django学习记录01

1.项目结构 djangoProject02 ├── manage.py 【项目的管理&#xff0c;启动项目、创建app、数据管理】【不要动】【常常用】 └── jangoProject02 ├── __init__.py ├── settings.py 【项目配置】 【常常修改】 ├── urls.py …

为什么要配置环境变量?

华子目录 什么是环境变量&#xff1f;Path环境变量使用%%引用环境变量操作步骤 使用%%引用环境变量的优点 用户变量和系统变量的区别 什么是环境变量&#xff1f; 环境变量&#xff1a;一般是指再操作系统中用来指定操作系统运行环境的一些参数&#xff0c;如&#xff1a;临时…

SpringBoot注解--07-- lombok 注解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1 Lombok介绍1.1 Lombok是什么?1.2 如何安装Lombok? 2 Lombok注解2.1 GetterSetter2.2 ToString2.3 EqualsAndHashCode2.4 NoArgsConstructor &#xff0c; Requi…

java仓库进销存商品库存管理系统springboot+vue

库存管理信息系统研究的内容涉及库存管理的全过程&#xff0c;包括入库、出库、退 货、订货、库存统计查询等等。 根据上述工作流程&#xff0c;库存管理系统将包含以下内容 1&#xff09;登录信息的输入&#xff0c;密码的修改。 2&#xff09;基本信息的输入&#xff0c;包括…

JAVA Web 学习(四)RabbitMQ、Zookeeper

十、消息队列服务器——RabbitMQ RabbitMQ是使用Erlang语言开发的开源消息队列系统&#xff0c;基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、 安全。AMQP协议更多用在企业系统内&#xff0c;对数据一致性、稳定性和可靠性要求…

【实战】阿里智能编码助手通义灵码

文章目录 前言技术积累通义灵码是什么&#xff1f;Copilot是什么&#xff1f;通义灵码主要功能通义灵码有哪些优势&#xff1f;通义灵码支持语言/工具通义灵码接入方式通义灵码帮助中心 实战演示安装插件行/函数级实时续写自然语言生成代码代码优化单元测试生成代码注释生成解释…

Spring 事务原理总结三

今天这篇文章&#xff0c;我想梳理一下Spring事务用到的几个核心组件。这些核心组件是我们理解Spring事务原理的基础。通过它们我们可以体会学习一下Spring设计者设计Spring事务时的基本思路。这些组件是&#xff1a;TransactionInfo、TransactionStatus、TransactionManager、…

【Qt+MSVC2017_64bit +Cmake新建项目编译出错】

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目新电脑环境配置 QtMSVC2017_64bit Cmake新建项目编译出错 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; QtMSVC2017_64bit Cmake新建项目编译出错 Running C:\Program Fil…

Java语法学习线程基础

Java语法学习线程基础 大纲 概念创建线程线程终止常用方法用户线程和守护线程线程的七大状态线程的同步互斥锁线程死锁释放锁 具体案例 1.概念 2. 创建线程 第一种&#xff1a; class Cat extends Thread {int time 0;Overridepublic void run() {while (true) {System.o…

Ubuntu 添加字体

Ubuntu 添加字体 Ubuntu如何添加新的字体&#xff1f;似乎远远没有Windows方便呀&#xff0c;查询了一些资料&#xff0c;与大家分享。 方法1 根据字体名称直接安装 oyroy-FMVU08001:~$ sudo apt-get install fonts-wqy-zenhei [sudo] roy 的密码&#xff1a; 正在读取软件…

基于springboot篮球竞赛预约平台源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;篮球竞赛预约平台也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

【数位dp】【动态规划】【KMP】1397. 找到所有好字符串

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1397. 找到所有好字符串 给你两个长度为 n 的字符串 s1 和 s2 &#xff0c;以及一个字符串 evil 。请你返回 好字符串 的数目。 好字符串 的定义为&#x…

7隐藏进程_Linux_Rootkit.md

Xcellerator 密码学Linux其他逆向工程 文章目录 [Linux Rootkit 第 7 部分&#xff1a;隐藏进程](https://xcellerator.github.io/posts/linux_rootkits_07/)选择要隐藏的 PID隐藏 PID Linux Rootkit 第 7 部分&#xff1a;隐藏进程 2020-10-01 :: TheXcellerator # linux #…