- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
数组也是一种复合数据类型,在数组可以存储多个不同类型的数据 。
- 数组中存储的是有序的数据,数组中的每个数据都有一个唯一的索引可以通过索引来操作获取数据
- 数组中存储的数据叫做元素
- 任何类型的值都可以成为数组中的元素
// 通过Array创建数组
const arr = new Array()
// 通过[]创建数组
const arr = []
// 通过索引添加元素
arr[0] = "test"
// 如果索引不是连续的,中间的索引也会创建,只是元素是空,应该避免使用非连续数组,性能不好
arr[3] = "2"
// 定义的时候添加元素
const a = new Array(1,3,4)
const arr = ["1","test"]
// 通过索引读取,如果读取一个不存在的元素,返回undefined
const arr = ["1","test"]
arr[0] // "1"
// 获取的实际值是数组的最大的索引+1,非连续数组因为有空值,不会特别准确
console.log(arr.length)
// 向数组的最后添加元素
arr[arr.length] = "3"
// 修改长度,如果改大了,多出的部分会是空元素,如果改小,会从后往前删除元素
arr.length = 10
arr = [1,2,3,4,5,6,7,8,9,10]
// 通过长度遍历-正序
for(let i=0; i < arr.length;++){
console.log(arr[i])
}
// 通过长度遍历-倒序
for(let i=arr.length-1;i>=0;i--){
console.log(arr[i])
}
// for-of语句可以用来遍历可迭代对象
for(let a of arr){
console.log(a)
}
方法大全 。
// 检查一个对象是否是数组
let arr = []
console.log(Array.isArray(arr)) // true
let arr = [1,2,3]
// 根据索引获取数组中的指定元素,
console.log(arr.at(2))
let arr = [1,2,3]
let arr1 = [4,5,6]
// 用来连接两个或多个数组
// 非破坏性方法,不会影响原数组,而是返回一个新的数组
let new_arr = arr.concat(arr1,[7,8])
console.log(new_arr) // [1,2,3,4,5,6,7,8]
let arr = [1,2,3,2]
// 获取元素在数组中第一次出现的索引
// 参数:要查询的元素,查询的起始位置
console.log(arr.indexOf(2)) // 1
console.log(arr.indexOf(2,2)) // 3
let arr = [1,2,3,2]
// 获取元素在数组中最后一次出现的位置,找到了则返回元素的索引,没有找到返回-1
console.log(arr.lastIndexOf(2)) // 3
let arr = [1,2,3,2]
// 将一个数组中的元素连接为一个字符串
console.log(arr.join("~")) // 1~2~3~2
let arr = [1,2,3,2]
// 用来截取数组(非破坏性方法)
/*
参数:1.截取开始的索引(包括该索引元素)
2.截取的结束索引(不包括该索引元素,该参数可以省略不写,如果省略则会一直截取到最后
如果将两个参数全都省略,则可以对数组进行浅拷贝
*/
console.log(arr.slice(0,2)) // [1,2]
// arr1和arr不是复制,两个指向的是一个内存地址,修改任意一个会影响其他数组
let arr = [1,2,3,2]
let arr1 = arr
/*
浅拷贝
通常对对象的拷贝都是浅拷贝
浅拷贝对对象的浅层进行复制(只复制一层)
如果对象中存储的数据是原始值,那么拷贝的深浅是不重要
浅拷贝只会对对象本身进行复制,不会复制对象中的属性(或元素)
调用slice时,会产生一个新的数组对象,从而完成对数组的复制- 浅拷贝
*/
let arr2 = [{"name":"l"},{"name":"q"}]
let arr3 = arr.slice()
/*
深拷贝
深拷贝指不仅复制对象本身,还复制对象中的属性和元素
因为性能问题,通常情况不太使用深拷贝
*/
let arr4 = [{"name":"l"},{"name":"q"}]
let arr5 = structuredClone(arr4)
let arr = [{"name":1},{"name":2}]
// 可以将一个数组中的元素展开到另一个数组中或者作为函数的参数传递,
// 浅复制
let arr2 = [...arr]
console.log(arr2) // [ { name: 1 }, { name: 2 } ]
/*
Object.assign(目标对象, 被复制的对象)
将被复制对象中的属性复制到目标对象里,并将目标对象返回
*/
const obj = {"name":1}
const obj1 = Object.assign({},obj)
console.log(obj1) // { name: 1 }
const obj = {"name":1}
const obj1 = Object.assign({"age":1},obj)
console.log(obj1) // { age: 1, name: 1 }
// 也可以使用展开运算符进行对象复制
const obj = {"name":1}
const obj1 = {...obj}
console.log(obj1) // { name: 1 },将obj中的属性在新对象中展开
const arr = []
// 向数组的末尾添加一个或多个元素,并返回新的长度
let l = arr.push(1,2,3)
console.log(l) // 3
console.log(arr) // [ 1, 2, 3 ]
const arr = [1,2,3,4,5]
// 删除并返回数组的最后一个元素
let a = arr.pop()
console.log(a) // 5
console.log(arr) // [ 1, 2, 3, 4 ]
console.log(arr.length) // 4
const arr = [1,2,3,4,5]
// 向数组的开头添加一个或多个元素,并返回新的长度
let a = arr.unshift(99,98)
console.log(a) // 7
console.log(arr) // [99, 98, 1, 2, 3, 4 ]
const arr = [1,2,3,4,5]
// 删除并返回数组的第一个元素
let a = arr.shift()
console.log(a) // 1
console.log(arr) // [ 2, 3, 4, 5]
console.log(arr.length) // 4
// 可以删除、插入、替换数组中的元素
// 参数:1. 删除的起始位置 2. 删除的数量 3. 要插入的元素 返回值:删除的元素
// 删除元素
const arr = [1,2,3,4,5]
let a = arr.splice(1,2)
console.log(a) // [2,3]
console.log(arr) // [1,4,5]
// 替换元素
const arr = [1,2,3,4,5]
let a = arr.splice(1,1,"ao") // 可以写多个元素
console.log(a) // [2]
console.log(arr) // [ 1, 'ao', 3, 4, 5 ]
// 插入元素
const arr = [1,2,3,4,5]
let a = arr.splice(1,0,"ao","to") //在下表为1的地方开始插入ao,to,后续元素后移
console.log(a) // []
console.log(arr) // [ 1, 'ao','to', 2, 3, 4, 5 ]
// 反转数组
const arr = [1,2,"a","s",5]
arr.reverse()
console.log(arr) // [ 5, 's', 'a', 2, 1 ]
const arr = [1, 2, 3, 2, 4, 1];
// 使用set方法去重
const arr1 = [...new Set(arr)];
console.log(arr1); // [1, 2, 3, 4]
// 循环判断去重
const arr = [1, 2, 1, 3, 2, 2, 4, 5, 5, 6, 7]
const newArr = []
for(let ele of arr){
if(newArr.indexOf(ele) === -1){
newArr.push(ele)
}
}
console.log(newArr)
如果一个函数的参数或返回值是函数,则这个函数就称为高阶函数 将函数作为参数,意味着可以对另一个函数动态的传递代码 。
function user(fn,age){
fn(age)
}
function admin(age){
return age === 18;
}
// 一个函数当做参数传递给另一个函数,这个函数称作回调函数(callback)
user(admin,18)
// 通常回调函数使用匿名函数定义
user(a => age === 18,18)
可以通过高阶函数,来动态的生成一个新函数 。
function a(){
return "hello"
}
function b(fn){
return () => {
// ... 其他自定义代码
return fn()
}
}
可以利用函数,来隐藏不希望被外部访问到的变量 。
闭包: 闭包就是能访问到外部函数作用域中变量的函数 。
什么时候使用: 当我们需要隐藏一些不希望被别人访问的内容时就可以使用闭包 。
构成闭包的条件:
1. 函数的嵌套
内部函数要引用外部函数中的变量 。
内部函数要作为返回值返回 。
function Sum() {
let num = 0 // 位于Sum作用域中
return () => {
num++
return num
}
}
const newFn = new Sum()
console.log(newFn()) // 1
console.log(newFn()) // 2
console.log(newFn()) // 3
函数的作用域在函数创建时就已经确定(词法作用域),和调用位置无关 。
// 闭包的原理就是利用词法作用域
let a = "全局"
function one(){
console.log(a) // 全局
return a
}
function two(){
let a = "局部"
console.log(a) // 局部
one() // 全局
function three(){
console.log(a) // 局部,函数定义是外部变量a是two中的a
}
return three
}
let fn = two()
fn()
闭包的生命周期:
注意事项:
相较于类来说,闭包比较浪费内存空间(类可以使用原型而闭包不能) 。
调用自身的函数称为递归函数 。
递归的作用和循环是基本 一致的 。
function test(num){
// 终止条件
if (num === 1){
return 1
}
// 调用自身
return test(num-1) * num
}
递归的核心思想就是将一个大的问题拆分为一个一个小的问题,小的问题解决了,大的问题也就解决了 。
编写递归函数,一定要包含两个要件:
递归的作用和循环是一致的,不同点在于,递归思路的比较清晰简洁,循环的执行性能比较好 在开发中,一般的问题都可以通过循环解决,也是尽量去使用循环,少用递归 只在一些使用循环解决比较麻烦的场景下,才使用递归 。
/*
sort用来对数组进行排序(会对改变原数组)
sort默认会将数组升序排列
注意:sort默认会按照Unicode编码进行排序,所以如果直接通过sort对数字进行排序
可能会得到一个不正确的结果
参数:
- 可以传递一个回调函数作为参数,通过回调函数来指定排序规则
(a, b) => a - b 升序排列
(a, b) => b - a 降序排列
*/
let arr = [3,3,4,6,8,1,2,10]
arr.sort((a,b) => a -b)
console.log(arr)
/*
用来遍历数组
需要一个回调函数作为参数,这个回调函数会被调用多次
数组中有几个元素,回调函数就会调用几次
每次调用,都会将数组中的数据作为参数传递
回调函数中有三个参数:
element 当前的元素
index 当前元素的索引
array 被遍历的数组
*/
let arr = [3,3,4,6,8,1,2,10]
arr.forEach((element,index,array)=>{
console.log(element)
console.log(index)
console.log(array)
})
/*
将数组中符合条件的元素保存到一个新数组中返回
需要一个回调函数作为参数,会为每一个元素去调用回调函数,并根据返回值(true、false)来决定是否将元素添加到新数组中
非破坏性方法,不会影响原数组
*/
/*
根据当前数组生成一个新数组
需要一个回调函数作为参数,
回调函数的返回值会成为新数组中的元素
非破坏性方法不会影响原数组
*/
let a = ["商城","账户","登录","注册"]
let b = a.map(ele => "<li>" + ele + "</li>")
console.log(b) // [ '<li>商城</li>', '<li>账户</li>', '<li>登录</li>', '<li>注册</li>' ]
/*
可以用来将一个数组中的所有元素整合为一个值
参数:
1. 回调函数,通过回调函数来指定合并的规则
2. 可选参数,初始值
*/
let arr = [1,2,3,4,5,6,7,8,10]
let b = arr.reduce((a,b) => a+b)
console.log(b) // 46
let arr2 = [1,2,3,4,5,6,7,8,10]
let b2 = arr2.reduce((a,b) => a+b,10)
console.log(b2) // 56
/*
arguments是函数中又一个隐含参数
arguments是一个类数组对象(伪数组)
和数组相似,可以通过索引来读取元素,也可以通过for循环变量,但是它不是一个数组对象,不能调用数组的方法
arguments用来存储函数的实参,
无论用户是否定义形参,实参都会存储到arguments对象中
可以通过该对象直接访问实参
*/
function test(){
console.log(arguments) // { '0': 1, '1': 3, '2': 4 }
console.log(arguments[0]) // 1
}
test(1,3,4)
/*
可变参数,在定义函数时可以将参数指定为可变参数
- 可变参数可以接收任意数量实参,并将他们统一存储到一个数组中返回
- 可变参数的作用和arguments基本是一致,但是也具有一些不同点:
1. 可变参数的名字可以自己指定
2. 可变参数就是一个数组,可以直接使用数组的方法
3. 可变参数可以配合其他参数一起使用,当可变参数和普通参数一起使用时,需要将可变参数写到最后
*/
function test(...args){
console.log(args) // [ 1, 3, 4 ]
console.log(args[0]) // 1]
}
test(1,3,4)
调用函数除了通过函数()调用外,还可以通过其他的方式调用 。
function test(){
return "hello"
}
test.call() // "hello"
test.apply() // "hello"
/*
call 和 apply除了可以调用函数,还可以用来指定函数中的this
call和apply的第一个参数,将会成为函数的this
通过call方法调用函数,函数的实参直接在第一个参数后一个一个的列出来
*/
class User{
name = "l"
age = 18
}
function test(a,b){
console.log(this.name) // name
console.log(this) // User { name: 'l', age: 18 }
console.log(a) // 1
console.log(b) // 2
}
let user = new User()
// 指定test函数的this是user对象
test.call(user,1,2)
// 通过apply方法调用函数,函数的实参需要通过一个数组传递
class User{
name = "l"
age = 18
}
function test(a,b){
console.log(this.name) // name
console.log(this) // User { name: 'l', age: 18 }
console.log(a) // 1
console.log(b) // 2
}
let user = new User()
// 指定test函数的this是user对象
test.apply(user,[1,2])
bind() 是函数的方法,可以用来创建一个新的函数 。
- bind可以为新函数绑定this
- bind可以为新函数绑定参数
箭头函数没有自身的this,它的this由外层作用域决定 。
- 无法通过call apply 和 bind修改它的this
- 箭头函数中没有arguments
class User{
name = "l"
age = 18
}
function test(a){
console.log(a) // 10
console.log(this.name) // l
}
const user = new User()
// 指定新函数的this和参数,如果是原函数()调用,则走原函数的参数和this
const newFn = test.bind(user,10)
newFn()
最后此篇关于Js数组&高阶函数的文章就讲到这里了,如果你想了解更多关于Js数组&高阶函数的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!