数组扩展方法(二)

以下将对Array.prototype上的方法进行整理,es5中数组遍历的方法在 数组扩展方法(一)可以查看

会改变原始数组

以下方法都在Array.prototype原型上

  1. push 数组尾部插入元素
  2. shift 数组首部删除元素
  3. unshift 向数组首部添加元素
  4. pop 数组尾部删除
  5. reverse 反转数组
  6. splice 删、插、替换数组
  7. sort 数组排序
  8. toString 数组转换为字符串

不会改变原数组

以下方法都在Array.prototype原型上
indexOf 获取元素索引值
lastIndexOf 获取元素索引值
conat 拼接数组
slice 截取数组
join 数组按指定符号转为字符串

工具方法

Array.prototype.indexOf

indexOf的英文意思为索引值为。
Array.prototype.indexOf:返回在数组中可以找到给定元素的第一个索引。
indexOf方法的注意事项:

  1. indexOf方法使用的是===全等运算。
  2. 注意是指定元素在数组中第一次出现的索引值。
  3. 如果指定元素不存在的话,返回-1
  4. 返回值是指定元素在数组中第一次出现的索引值,不存在时返回-1
  5. 参数问题:
    1. searchElement:指定查找的元素。
    2. fromIndex:开始查找的位置。如果该索引值大于数组长度,意味着不会在数组中查找,返回-1。如果参数中提供的索引值是一个负值,则意味将其作为数组末尾的一个抵消,即-1相当于arr.length - 1-2相当于arr.length - 2。注意:虽然fromIndex可能是负数,但是查询的顺序依旧是从前往后。如果抵消后的索引值小于0,则整个数组都会被查询,默认值为0。
const array = [2, 9, 9];

array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0
重写indexOf
Array.prototype.myIndexOf = function(){
  let arr = this,
      len = arr.length,
      item = null,
      arg1 = arguments[0],
      arg2 = arguments[1] || 0,
      i = 0;
  
  //   fromIndex:开始查找的位置。如果该索引值大于数组长度,意味着不会在数组中查找,返回-1。
  //   如果参数中提供的索引值是一个负值,则意味将其作为数组末尾的一个抵消,即-1相当于arr.length - 1,-2相当于arr.length - 2。
  //  注意:虽然fromIndex可能是负数,但是查询的顺序依旧是从前往后。如果抵销后的索引值小于0,则整个数组都会被查询,默认值为0。
  if(arg2 > len) return -1;
  if(!arg1) return -1;
  i  = arg2 < 0 ? (arg2 + len < 0 ? 0 : arg2 + len) : arg2;
  // 这里说明一点,使用for...i...遍历,会遍历出稀松数组,建议使用for...in...遍历
  for(i ; i < len ; i++){
    if(arr[i] === arg1 ){
      return i;
    }
    if(i === len - 1 && arg1 !== arr[i]){
      return -1;
    }
  }
}
const array = [2, 9, 9];
console.log(array.myIndexOf(2));   // 0
console.log(array.myIndexOf(7));     // -1
console.log(array.myIndexOf(9, 2));  // 2
console.log(array.myIndexOf(2, -1)); // -1
console.log(array.myIndexOf(2, -3)); // 0
Array.prototype.lastIndexOf

lastIndexOf的英文意思是最后的索引值。
Array.prototype.lastIndexOf:方法返回指定元素在数组中最后一个索引值。如果不存在则返回-1。从数组的后面项向前查找,从fromIndex处开始。
lastIndexOf需要我们注意的有以下几点:

  1. 参数的问题
    1. searchElement:被查找的元素。
    2. fromIndex:从此位置开始逆向查找。默认为数组的长度减1(arr.length - 1 ),即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,数组仍然会从后向前查找。如果该负值的绝对值大于数组长度,则方法返回-1,即数组不会被查找。
  2. 返回值是数组在该元素最后一次出现的索引值,如未找到返回-1.
  3. lastIndexOf使用严格相等===比较searchElement和数组中元素。
var array = [2, 5, 9, 2];
var index = array.lastIndexOf(2);
// index is 3
index = array.lastIndexOf(7);
// index is -1
index = array.lastIndexOf(2, 3);
// index is 3
index = array.lastIndexOf(2, 2);
// index is 0
index = array.lastIndexOf(2, -2);
// index is 0
index = array.lastIndexOf(2, -1);
// index is 3
重写 lastIndexOf
Array.prototype.myLastIndexOf = function(){
  let arr = this,
      len = arr.length,
      arg1 = arguments[0],
      arg2 = arguments[1] || len,
      i = 0;
  if(!arg1 || Math.abs(arg2) > len) return -1;
  // if(arg2 >= len) i = len;
  // if(arg2 < 0 ) i = arg2 + len;
  // if(0 <= arg2 < len) i = arg2;
  i = arg2 >= len ? len : (arg2 < 0 ?(arg2 + len):arg2);

  for (i; i >= 0; i--) {
    if(arg1 === arr[i]) return i;
    if(i == 0 && arg1 !== arr[i]) return -1;
  }
}

var array = [2, 5, 9, 2];
console.log(array.myLastIndexOf(2)); // 3
console.log(array.myLastIndexOf(7)); // -1
console.log(array.myLastIndexOf(2, 3)); // 3
console.log(array.myLastIndexOf(2, 2)); // 0
console.log(array.myLastIndexOf(2, -2)); // 0
console.log(array.myLastIndexOf(2, -1)); // 3
比较新颖的示例

使用lastIndexOf查找到一个元素在数组中所有的索引,并使用push将所有添加到另一个数组中。

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var searchElement = 'a';
var idx = array.lastIndexOf(searchElement);
while(idx !== -1) {
	indices.push(idx);
	idx = (idx > 0 ? array.lastIndexOf(searchElement, idx - 1) : -1);
}
console.log(indices);
Array.prototype.join

Array.prototype.join:将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
join方法需要我们注意的有以下几点:

  1. 参数问题:
    1. separator分隔符,如果需要,将分隔符转换为字符串。如果省略该值,数组元素用,分隔。如果separator是空字符串"",则所有元素之间都没有任何字符
  2. 返回值是一个数组元素连接的字符串。如果arr.length为0,则返回空字符串。
  3. 如果一个元素是undefinednull,它被转换空字符串。
  4. 这是数组转为字符串的一种方式。
示例

连接类数组对象。

function f(a, b, c) {
	var s = Array.prototype.join.call(arguments);
	console.log(s); // '1, a, true'
}
f(1, 'a', true)

undefined/null被转换为空字符串。

var arr = [undefined, null, 1];
console.log(arr.join()); // ,,1
数组扁平化

join方法带参数的话,只能将数组扁平化一层
join方法不带参数的话,直接将数组扁平化

// 带参数的话,只能将数组扁平化一层
console.log([1,[2,[3,4,5]]].join('-')); // 1-2, 3, 4, 5

// 不带参数的话,直接数据扁平化,默认分隔
console.log([1,[2,[3,4,5]]].join()); // 1, 2, 3, 4, 5
重写join方法
Array.prototype.myJoin = function (/*separator*/) {
	var t = this,
		// 保存数组索引值
		index = t.length - 1,
		// 分隔符
		separator = arguments[0] !== undefined ? arguments[0] : ',',
		// 结果字符串
		restr = '';

	// 遍历需要分割的数组
	for (var key in t) {
		if (t.hasOwnProperty(key)) {
			// 处理undefined和null问题,转为空字符串
			if (t[key] === undefined || t[key] === null) {
				restr += separator;
				continue;
			}
			// 字符串最后一个separator问题
			if (key == index) {
				restr += t[key]
				return restr;
			}
      console.log(t[key]);
			restr += t[key] + separator;
		}
	}
}

// 当一个数组被作为文本值或者进行字符串拼接操作时,将会自动调用其 toString 方法。
Array.prototype.toString

Array.prototype.toString:方法返回一个字符串,表示指定的数组及其元素。
toString方法需要我们注意的有以下几点:

  1. 无参数。
  2. 返回值是一个表示数组所有元素的字符串。
toString 方法描述

Array对象覆盖了ObjecttoString方法。对于数组对象,toString方法在内部调用join方法拼接数组中的元素中并返回一个字符串,其中包含逗号分割的每个数组元素。如果join方法不可用,或者它不是一个函数,将使用Object.prototype.toString代替,并返回[object Array]
当一个数组被作为文本值或者进行字符串拼接操作时,将会自动调用其 toString 方法。

const arr = [];
arr.join = 1;
console.log(arr.toString());

console.log(Array.prototype.toString.call({join: () => 1})); // 1
数组扁平化

toString方法能够将多维数组进行扁平化。

console.log(Array.prototype.toString.call([1, 2, 3, 4])); // 1,2,3,4
console.log(Array.prototype.toString.call([[1, 2], [3, 4]])); // 1,2,3,4
Array.from

Array.from()方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例对象。
Array.from()需要注意的有以下几点

  1. 参数问题
    1. arrayLike:想要转为数组的伪数组对象或可迭代对象。
    2. mapFn:如果制定了该参数,新数组中的每个元素都会执行该回调函数。
    3. thisArg:可选参数,执行回调mapFnthis对象。

返回值:一个新的数组实例。

// 下面是一个类似数组的对象,Array.from将它转为真正的数组。
let arrayLike = {
  '0':'a',
  '1':'b',
  '2':'c',
  length:3
}
// es6 写法
let arr2 = Array.from(arrayLike) ; // ['a','b','c']

实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。

let dom = document.querySelectorAll('div');
let domArray = Array.from(dom)

只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。

console.log(Array.from('hello')); //  ['h', 'e', 'l', 'l', 'o']
console.log('hello'.__proto__);

image.png

let namesSet = new Set(['a','b','b']);
console.log(Array.from(namesSet));
// ['a', 'b']

上面代码中,字符串和 Set 结构都具有 Iterator 接口,因此可以被Array.from转为真正的数组。
如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组。
值得提醒的是,扩展运算符(…)也可以将某些数据结构转为数组。

function foo(){
  const arg = [...arguments]
}

[...document.querySelectorAll('div')]

扩展运算符背后调用的是遍历器接口(Symbol.iterator),如果一个对象没有部署这个接口,就无法转换。Array.from方法还支持类似数组的对象。所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。

console.log(Array.from({length:3}));
// [undefined, undefined, undefined]

上面代码中,Array.from返回了一个具有三个成员的数组,每个位置的值都是undefined。扩展运算符转换不了这个对象。

  1. 重写from方法
Array.myFrom = function (iteratorObj, callback) {
	// this指向
	var thisArg = arguments[2] !== undefined ? arguments[2] : window;
	var isIterable = iteratorObj[Symbol.iterator] || iteratorObj.hasOwnProperty('length');

	// 创建一个数组
	var resArr = [];
	// 计步器
	var index = 0;
	if (isIterable) {
		if (iteratorObj.hasOwnProperty('length')) {
			for (var key in iteratorObj) {
				if (typeof callback === 'function') {
					key !== 'length' ? resArr[index] = callback.apply(thisArg, [iteratorObj[key], index++]) : '';
				}else{
          key !== 'length' ? resArr[index++] = iteratorObj[key] : ''
        }
			}
		} else {
			for (var value of iteratorObj) {
				if (typeof callback === 'function') {
					resArr[index] = callback.apply(thisArg, [value, index++]);
				}else{
          resArr[index++] = value;
        }
			}
		}
		index = 0;
	}
	return resArr;
}

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

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

相关文章

深入探究:AVL树的平衡之道

文章目录 一、AVL树的原理AVL树的定义和特性平衡因子的概念 二、AVL树的自平衡策略a. 单旋&#xff08;single rotation&#xff09;1. 左单旋&#xff08;Left Rotation&#xff09;&#xff1a;2. 右单旋&#xff08;Right Rotation&#xff09;&#xff1a; b. 双旋&#xf…

双向数据绑定:Vue.js的魔法背后

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【PHP+代码审计】PHP基础——流程控制

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

大规模自动化重构框架--OpenRewrite浅析

目录 1. OpenRewrite是什么&#xff1f;定位&#xff1f; 2. OpenWrite具体如何做&#xff1f; 3. 核心概念释义 3.1 Lossless Semantic Trees (LST) 无损语义树 3.2 访问器&#xff08;Visitors&#xff09; 3.3 配方&#xff08;Recipes&#xff09; 4. 参考链接 Open…

FPGA 按键控制串口发送

按键消抖 消抖时间一般为10ms&#xff0c;我使用的板子是ACX720&#xff0c;晶振为50MHZ&#xff0c;20ns为一周期。 状态机 模块设计 设计文件 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2023/01/11 12:18:36 // Design Name: // Module Name…

Linux应用 inotify监控文件变化

1、前言 inotify是Linux内核提供的一种文件系统监控机制&#xff0c;可以用来监视文件系统的变化&#xff0c;如文件创建、删除、修改、移动等。通过inotify&#xff0c;用户空间程序可以实时获取文件系统的变化事件&#xff0c;并做出相应的处理。 主要特点&#xff1a; 实…

C++进阶之路---二叉搜索树详解 | 具体实现

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、二叉搜索树简介 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&am…

设计模式九:装饰器模式

文章目录 1、装饰器模式2、示例3、装饰器模式与适配器模式4、装饰器模式和代理模式5、java io流的装饰器模式 1、装饰器模式 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。这种类型的设计模式属于结构…

H5 微商宣传引流跳转微信单页源码

源码名称&#xff1a;H5 微商宣传引流跳转微信单页源码 源码介绍&#xff1a;一款微商宣传引流单页源码&#xff0c;源码带有导师微信二维码&#xff0c;点击复制微信号并跳转到微信功能【跳转后需自行贴贴搜索】。可用于各种微商团队宣传。 需求环境&#xff1a;H5 下载地址…

如何将应用一键部署至多个环境?丨Walrus教程

在 Walrus 平台上&#xff0c;运维团队在资源定义&#xff08;Resource Definition&#xff09;中声明提供的资源类型&#xff0c;通过设置匹配规则&#xff0c;将不同的资源部署模板应用到不同类型的环境、项目等。与此同时&#xff0c;研发人员无需关注底层具体实现方式&…

基与HTML5的塔防游戏设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 项目背景与相关技术 3 1.1 背景与发展简介 3 1.2 HTML5技术及其优势 4 1.3 JavaScript开发的优势与劣势 4 1.4 CSS样式表在开发中的用处 5 1.5 本章小结 6 2 系统分析 7 2.1 需求分析 7 2.2 问题分析 7 2.3 流程设计 7 2.3 功能分析 8 2.…

私立医院的革命者:大数据解决方案全面解析

第一部分&#xff1a;背景 在信息化飞速发展的今天&#xff0c;医疗行业正经历着一场深刻的数字化转型。特别是对于私立医院来说&#xff0c;要在这个变革的浪潮中立于不败之地&#xff0c;就必须拥抱新技术&#xff0c;优化服务流程&#xff0c;提高医疗质量。大数据技术&…

基于深度学习的植物类别检测系统(含UI界面、yolov8、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 可以任意更换主干结构&#xff0c;支持几百种网络主干。 数据集&#xff1a;     网上下载的数据集&#x…

【Linux】常见的基本指令(下)

在本篇博客中&#xff0c;继续介绍Linux的常见的基本指令。 一.find指令 find指令是一条搜索指令&#xff0c;在目录结构中搜索文件。 find [目录名] -name [文件名] 在指定的目录下以文件名的搜索方式去搜索文件 二.which指令 which指令是只用来搜索命令在那个路径下…

Ableton Live 12 Suite:音乐创作的全能工作站 mac版

在数字音乐制作的领域中&#xff0c;Ableton Live 11 Suite 无疑是引领潮流的旗舰产品。作为一款综合性的音乐制作和演出软件&#xff0c;它提供了从创作灵感的萌芽到最终作品完成的全方位解决方案。 Ableton Live 12 Suite Mac版软件获取 Ableton Live 11 Suite 凭借其强大的…

登录与注册功能(简单版)(1)登录

目录 1、需求 2、怎样实现 3、步骤 1&#xff09;创建login.html 2&#xff09;创建user数据表 3&#xff09;IDEA连接数据库 4&#xff09;pom.xml中添加MyBatis和MySQL驱动坐标 5&#xff09;创建User实体类 6&#xff09;创建UserMapper.xml映射文件 7&#xff0…

实体好做,还是电商好做?最适合新手的是哪种?

我是电商珠珠 时间过得很快&#xff0c;距离2025年转眼间也就只剩下了9个月&#xff0c;部分人想要充分利用自己的时间去做一些可以赚钱的项目。 现在创业要么做实体店&#xff0c;要么做自媒体&#xff0c;要么就做电商。按照现在的经济发展趋势&#xff0c;开实体店甚至不能…

Tiktok视频播放为何为0?4大原因小白需了解

原因一、养号失败&#xff0c;被判为营销号 注册了tiktok账号以后&#xff0c;是需要一段时间进行养号&#xff0c;培养账号权重的&#xff01;而有些小伙伴未经养号&#xff0c;直接注册上手开始发视频&#xff01;这样很容易导致视频没有播放&#xff01;因为这样连续的一系…

比派电器T6白色系高速吹风机,高品质保证下,追求极致性价比

广东比派电器科技有限公司于2020年成立于东莞市松山湖高新技术企业园区融易大厦&#xff0c;公司聚焦于小家电的研发&#xff0c;生产&#xff0c;销售。专注在小家电的PCBA研发&#xff0c;产品设计&#xff0c;成品生产。提供小家电产品一站式解决方案&#xff0c;致力于成为…

铁威马TOS 6即将登场,全新设计更多功能抢先看!

错过了TOS 6内测的铁粉们注意啦&#xff01; 很高兴与大家宣布 铁威马TOS 6 Beta 将在本月与大家见面 时隔一年多 TOS 6历经严格测试与精细优化 焕然一新的用户界面 由内而外展现全新风采 今天小马就来给大家小剧透 TOS 6新功能抢先看 TOS 6是铁威马迄今为止“最友好最美…