草庐IT

JS数组方法中哪些会改变原数组,哪些不会?

东方睡衣 2023-11-12 原文

前言

作为一名前端开发人员,我们每天都会与数组打交道。JS 也提供了很多操作数组的原生 API 供我们调用。在这些方法里面,有的方法会改变原数组,有些不会改变原数组。别看这一点小小的区别,往往会造成巨大的影响,特别是在算法层面,有可能会造成算法复杂度的飙升。

今天我们就来好好理一理哪些数组方法操作会改变原数组,哪些数组方法不会改变原数组。

1.会改变原数组的方法

1.1 push

push 可以说是最常用的数组操作方法了,它也非常好理解,本身就是往数组里面添加元素的意思。

作用:

push 方法往数组里面添加元素,返回数组的长度。

示例代码:

let arr1 = ['小猪课堂', 23];
let length1 = arr1.push('张三');
console.log(arr1); // ['小猪课堂', 23, '张三']
console.log(length1); // 3 

上段代码中 arr1 数组是变化了的,push 方法返回的是数组最新的长度。

1.2 unshift

作用:

unshift 方法会在数组的开头添加一个元素,它会返回数组新的长度。

示例代码:

let arr2 = ['小猪课堂', 23];
let length2 = arr2.unshift('张三');
console.log(arr2); // ['张三', '小猪课堂', 23]
console.log(length2); // 3 

1.3 pop

作用:

pop() 方法从数组中删除最后一个元素,并返回该元素的值。

示例代码:

let arr3 = ['小猪课堂', 23];
let value1 = arr3.pop();
console.log(arr3); // ['小猪课堂']
console.log(value1); // 23 

1.4 shift

作用:

shift() 方法从数组中删除第一个元素,并返回该元素的值。

示例代码:

let arr4 = ['小猪课堂', 23];
let value2 = arr4.shift();
console.log(arr4); // [23]
console.log(value2); // 小猪课堂 

1.5 sort

作用:

sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的。它返回的就是排序后的数组。

示例代码:

let arr5 = [321, 23, 12, 6666, 2];
let value3 = arr5.sort();
console.log(arr5); // [12, 2, 23, 321, 6666]
console.log(value3); // [12, 2, 23, 321, 6666] 

注意:

因为 sort 的默认排序是将元素转化为字符串后排序的,所以上述代码中的排序结果可能不是我们想要的,想要获得正确的排序结果,我们可以传入一个函数,来规定排序的规则。

代码如下:

arr5.sort((a, b) => a - b);
console.log(arr5); // [2, 12, 23, 321, 6666] 

1.6 splice

作用:

splice() 方法用于添加或删除数组中的元素,如果删除一个元素,则返回一个元素的数组。 如果未删除任何元素,则返回空数组。

示例代码:

let arr6 = ['张三', '小猪课堂', 23];
let item1 = arr6.splice(0,1); // 删除一个元素,返回删除元素的数组
console.log(item1); // ['张三']
console.log(arr6); // ['小猪课堂', 23] 

1.7 reverse

作用:

reverse() 方法用于颠倒数组中元素的顺序。

示例代码:

let arr7 = ['张三', '小猪课堂', 23];
let item2 = arr7.reverse();
console.log(item2); // [23, '小猪课堂', '张三']
console.log(arr7); // [23, '小猪课堂', '张三'] 

2.不会改变原数组的方法

2.1 concat

作用:

concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

示例代码:

let arr8 = ['小猪课堂'];
let arr9 = ['张三'];
let arr10 = arr8.concat(arr9);
console.log(arr8); // ['小猪课堂']
console.log(arr9); // ['张三']
console.log(arr10); // ['小猪课堂', '张三'] 

2.2 join

作用:

join() 方法用于把数组中的所有元素转换一个字符串,元素是通过指定的分隔符进行分隔的。

示例代码:

let arr11 = [1, 2, 3, 4, 5, 6];
let item3 = arr1.join(',');
console.log(item3); // 小猪课堂,23,张三
console.log(arr11); // [1, 2, 3, 4, 5, 6] 

2.3 reduce

作用:

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。reduce 方法的使用情况稍微复杂,不熟悉的小伙伴建议去官网好好学学,它的应用范围还是挺宽泛的。

示例代码:

let arr12 = [1, 2, 3, 4, 5, 6];
let item4 = arr12.reduce((total,currentValue)=>{return total + currentValue;
}, 0);
console.log(item4); // 21
console.log(arr12); // [1, 2, 3, 4, 5, 6] 

2.4 map

作用:

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

示例代码:

let arr13 = [1, 2, 3, 4, 5, 6];
let item5 = arr13.map((item) => {return item + 100;
});
console.log(item5); // [101, 102, 103, 104, 105, 106]
console.log(arr13); // [1, 2, 3, 4, 5, 6] 

2.5 forEach

作用:

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

示例代码:

let arr14 = [1, 2, 3, 4, 5, 6];
let item6 = arr14.forEach((item) => {item + 100;
});
console.log(item6); // undefined
console.log(arr14); // [1, 2, 3, 4, 5, 6] 

注意:

forEach 方法没有返回值,而且它也不会改变原数组,有些同学误以为 forEach 会改变原数组,通常是因为在 forEach 方法的回调函数中,我们自己做了更改原数组的操作。

2.6 filter

作用:

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

示例代码:

let arr15 = [1, 2, 3, 4, 5, 6];
let item7 = arr15.filter((item) => {return item > 3;
});
console.log(item7); // [4, 5, 6]
console.log(arr15); // [1, 2, 3, 4, 5, 6] 

2.7 slice

作用:

slice() 方法可从已有的数组中返回选定的元素。slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。

示例代码:

let arr16 = [1, 2, 3, 4, 5, 6];
let item8 = arr15.slice(0, 3);
console.log(item8); // [1, 2, 3]
console.log(arr16); // [1, 2, 3, 4, 5, 6] 

2.8 findIndex

作用:

findIndex 接收一个测试函数,也可以叫做条件函数,最终返回满足该测试函数的元素的索引位置,如果没有找到符合条件的元素,则返回-1。如果满足条件的有多个,那么只会返回第一个满足条件的元素索引。

示例代码:

let arr17 = [1, 2, 3, 4, 5, 6];
let item9 = arr17.findIndex((item) => {return item > 2;
});
console.log(item9); // 2
console.log(arr17); // [1, 2, 3, 4, 5, 6] 

总结

数组方法基本上每一版本的 JS 中都会增加一些,本篇文章主要总结了我们开发中比较常用而且容易混淆的。至于为什么要区分是否更改原数组,那就得根据实际情况来决定了。打个比方,如果有一道算法题,可以用数组方法中的 unshiftslice 来解决,那么选用哪一个呢?首先 unshift 会改变原数组,它的事件复杂度是 O(n),而 slice 方法不会改变原数组,它的时间复杂度是 O(1),改用哪个一目了然。

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

有关JS数组方法中哪些会改变原数组,哪些不会?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  6. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  7. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  8. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  10. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

随机推荐