前端基础(四)- 数组和对象方法

本文介绍了JavaScript中的数组方法,如reduce、concat、every、some、flatMap等,以及一些较少使用的对象方法,如defineProperty、freeze、fromEntries等。这些方法涵盖了数组的合并、过滤、排序、操作等常见操作,以及对象的属性定义、冻结、密封等特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组的方法

Array.prototype.reduce()

reduce() 方法会对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值;第一次执行时没有上一次的结果,所以如果你没有设定初始值,那么这个初始值就是数组索引为 0 的元素,如果设定了初始值,迭代器会从第二个元素(索引为 1 的那个元素)开始执行函数

关于 reduce()的几个简单用法

// 1. 计算和
const arr = [1, 2, 3, 4];
const result1 = arr.reduce((pre, current) => {
  return pre + current;
});
console.log(result1); // 10
// reduce()传入第二个参数作为初始值
const arr2 = [1, 2, 3, 4];
const result2 = arr2.reduce((pre, current) => {
  return pre + current;
  //   return pre - curr > 0 ? pre : curr  也可获得最值
}, 5);
console.log(result2); // 15

// 2.获取数组中的最值
const arr3 = [1, 2, 3, 4, 9, 11, 34, 12, 55];
const result3 = arr3.reduce((pre, curr) => {
  return pre > curr ? pre : curr;
});
console.log(result3); // 55

/*
获取数组最值还可利用数学函数
*/
const arr4 = [1, 2, 3, 4, 9, 11, 34, 12, 55];
const result4 = Math.min(...arr4);
console.log(result4); // 1

// reduce() 结合Math函数更直接
const arr5 = [1, 2, 3, 4, 9, 11, 34, 12, 55];
const result = arr5.reduce((pre, curr) => {
  return Math.max(pre, curr);
});
console.log(result); // 55

// 3.二维数组转一维
// 当然数组扁平化最便捷的方式还是利用数组本身提供的方法Array.prototype.flat()
const arr6 = [
  [1, 2],
  [3, 4],
];
const result = arr6.reduce((pre, curr) => {
  return pre.concat(curr);
}, []);

console.log(result); // [1, 2, 3, 4]

// 4. 计算数组中每个元素出现的次数
const arr7 = [
  "apple",
  "banana",
  "noodles",
  "tomatoes",
  "pear",
  "apple",
  "tomatoes",
];
const result = arr7.reduce((pre, curr) => {
  if (curr in pre) {
    pre[curr]++;
  } else {
    pre[curr] = 1;
  }
  return pre;
}, {});

console.log(result); // {apple: 2, banana: 1, noodles: 1, tomatoes: 2, pear: 1}

// 5. 数组去重
const arr8: string[] = [
  "a",
  "b",
  "a",
  "b",
  "b",
  "c",
  "e",
  "e",
  "c",
  "d",
  "d",
  "d",
];
const result = arr8.reduce((pre: string[], curr: string) => {
  if (!pre.includes(curr)) {
    pre.push(curr);
  }
  return pre;
}, []);

console.log(result); // ['a', 'b', 'c', 'e', 'd']
// 当然更简单的去重方式是使用Set数据结构 console.log(Array.from(new Set(arr))) // ['a', 'b', 'c', 'e', 'd']

// 6. 数组过滤
// 数组的过滤数组本身也提供了方法:Array.prototype.filter()
const arr9 = [1, 4, 6, 7, 8, 12];
const result = arr9.reduce((pre: number[], curr) => {
  if (curr > 5) {
    pre.push(curr);
  }
  return pre;
}, []);
console.log(result); // [6, 7, 8, 12]

/*
in 操作符:用来判断某个属性是否属于某个对象,可以是对象的直接属性,也可以是prototype继承的属性
*/
const obj = { name: "tom", age: 12 };
console.log("name" in obj); // true
console.log("sex" in obj); // false

const arr1 = ["apple", "pear"];
console.log(0 in arr1); // true
console.log("apple" in arr1); // false
console.log("length" in arr1); // true  length 是数组的固有属性,所以为true

// 但是注意,in 的右边必须是一个对象
const str = new String("tom");
console.log("tom" in str); // false
console.log("length" in str); // true
const str1 = "tom";
// 下面写法在ts中还会直接报错
console.log("tom" in str1); // false
console.log("length" in str1); // false

Array.prototype.concat()

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是会返回一个新数组

const arr1 = [1, 2];
const arr2 = [3, 4];
const res = arr1.concat(arr2, 5);
console.log(res); // [1, 2, 3, 4,5]

Array.prototype.every()

every() 方法验证一个数组内的所有元素是否都能通过传入的指定函数的测试。返回布尔值
note:若接收一个空数组,此方法在一切情况下都返回 true

const arr = [1, 2, 4, 5, 6, 7];
const res = arr.every((currValue) => {
  return currValue > 5;
});
console.log(res); // false
/* every() 接收的第一个参数是一个函数,该函数有三个参数:
array.every((currValue,index?,currArr?)=>{})
currValue:用于测试的当前值
index:可选,用于测试的当前值的索引
currArr:可选,调用every方法的当前数组
*/

Array.prototype.some()

some() 方法测试数组中至少有 1 个元素通过被提供的函数测试。返回 Boolean

const arr = [1, 2, 46, 75, 99, 56, 2];
const res = arr.some((x) => x > 50);
console.log(res); // true

Array.prototype.flatMap()

flatMap() 方法使用映射函数映射每个元素,然后将结果形成一个新数组,再执行深度为 1 的 flat

// 基础用法
const arr = [1, 2, 3, 4];
const resMap = arr.map((item) => [item * 2]);
const resFlatMap = arr.flatMap((item) => [item * 2]);
console.log(resMap); // [[2], [4], [6], [8]]
console.log(resFlatMap); // [2, 4, 6, 8]

// 可能的用法
const arr = ["My name is Tom", "Lucy"];
const resFlatMap = arr.flatMap((item) => item.split(" "));
console.log(resFlatMap); // ['My', 'name', 'is', 'Tom', 'Lucy']

Array.from()

Array.from() 方法对一个类数组或可迭代对象创建一个新的,浅拷贝的数组实例

/*
Array.from(arrLike,mapFn?)
*arrLike:需要转换成数组的类数组对象或者可迭代对象
*mapFn:可选,生成的新数组执行的回调
*/

const arr = [1, 2, 3];
const res = Array.from(arr, (x) => x * 2);
const resArr = Array.from(arr);
console.log(res); // [2, 4, 6]
console.log(resArr); // [1, 2, 3]

const str = "first";
const resStr = Array.from(str); //  ['f', 'i', 'r', 's', 't']
console.log(resStr);

Array.prototype.includes()

includes() 方法用来判断一个数组是否包含一个指定的值,结果返回布尔值

const arr = ["Tom", "King", "Lucy"];
const res = arr.includes("Tom");
console.log(res); // true

/*
array.includes(toValue,fromIndex?)
*toValue:要查找的目标值
*fromIndex:可选,从指定索引处开始查询,如果为负,按升序从arr.length + fromIndex 处开始;formIndex大于或等于数组长度,则返回false,不搜索该数组
*/

Array.prototype.indexOf()

indexOf()方法返回在数组中可以找到的指定元素的第一个索引,如果不存在,返回-1

const arr = ["Tom", "King", "Lucy"];
const res = arr.indexOf("Tom");
const res2 = arr.indexOf("Jim");
console.log(res); // 0
console.log(res2); // -1

Array.prototype.join()

join() 方法将一个数组(或类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符

const arr = ["Tom", "My", "friend"];
const res1 = arr.join();
const res2 = arr.join("-");
const res3 = arr.join("_");
console.log(res1); // Tom,My,friend
console.log(res2); // Tom-My-friend
console.log(res3); // Tom_My_friend

Array.prototype.lastIndexOf()

lastIndexOf() 方法返回指定元素(即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始

const arr = ["Tom", "King", "Lucy"];
const res1 = arr.lastIndexOf("Tom");
const res2 = arr.lastIndexOf("Jim");
console.log(res1); // 0
console.log(res2); // -1

Array.prototype.pop()

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

const arr = ["Tom", "King", "Lucy"];
const res = arr.pop();

console.log(res, arr); // Lucy , ['Tom', 'King']

Array.prototype.push()

push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度

const arr = ["Tom", "King", "Lucy"];
const res = arr.push("Next", "Jack");

console.log(res, arr); // 5 ,  ['Tom', 'King', 'Lucy', 'Next', 'Jack']

Array.prototype.reverse()

reverse() 方法将数组中元素的位置颠倒,并返回该数组。该方法会改变原数组

const arr = ["Tom", "King", "Lucy"];
const res = arr.reverse();

console.log(res, arr); // ['Lucy', 'King', 'Tom'] , ['Lucy', 'King', 'Tom']

Array.prototype.shift()

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

const arr = ["Tom", "King", "Lucy"];
const res = arr.shift();

console.log(res, arr); // Tom, ['King', 'Lucy']

Array.prototype.slice()

slice() 方法返回一个新数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括 end)。原数组不被改变

const arr = ["Tom", "King", "Lucy"];
const res = arr.slice(2);

console.log(res, arr); // ['Lucy'], ['Tom', 'King', 'Lucy']

Array.prototype.sort()

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

const arr = [1, 2, 46, 75, 99, 56, 2, 100000];
const res = arr.sort();
console.log(res); // [1, 100000, 2, 2, 46, 56, 75, 99] // 没有指定的情况下,排序是按照先转换为字符串,然后按照Unicode上的编码排序,所以并不是正常的数字排序

const res2 = arr.sort((a, b) => a - b);
console.log(res2); // [1, 2, 2, 46, 56, 75, 99, 100000]

const res3 = arr.sort((a, b) => b - a);
console.log(res3); // [100000, 99, 75, 56, 46, 2, 2, 1]

Array.prototype.splice()

splice() 方法通过删除或替换现有元素或者添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组

/*
array.splice(startIndex,deleteCount?,...items?)
*startIndex:修改开始的位置(从0开始),如果大于数组长度,则从数组末尾开始,如果是负数,则从末尾开始的第几位(从-1开始计数,-n是倒数第n个元素,等价于array.length-n),如果负数的绝对值大于了数组长度,则从第0项开始
*deleteCount:可选,要删除的数组元素的个数,如果被省略或者大于了startIndex之后的元素个数,则从startIndex开始后面的元素都被删除,如果为0或者负数,则不删除元素,这时应该添加一个元素
*items:可选,要添加进数组的元素,从startIndex位置开始,如果没有,则只删除元素
*/

// ------------ 从第一个索引开始,删除一个元素
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(1, 1);
console.log("被删掉的元素:", res); // ['King']
console.log("改变后的原数组:", arr); // ['Tom', 'Lucy', 'Jack', 'Jim']

// ------------- 从第一个索引开始,删除后面所有元素
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(1);
console.log("被删掉的元素:", res); // ['King', 'Lucy', 'Jack', 'Jim']
console.log("改变后的原数组:", arr); // ['Tom']

// ------------- 从倒数第三个元素开始,删除后面所有元素
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(-3);
console.log("被删掉的元素:", res); //['Lucy', 'Jack', 'Jim']
console.log("改变后的原数组:", arr); //['Tom', 'King']

// ------------ 从第一个索引开始,删除10个元素,大于剩余元素总数,删除后面所有元素
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(1, 10);
console.log("被删掉的元素:", res); // ['King', 'Lucy', 'Jack', 'Jim']
console.log("改变后的原数组:", arr); // ['Tom']

// ------------ 从第二个索引开始,删除-1个元素,指定数量为负数,不删除,原数组不变
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(2, -1);
console.log("被删掉的元素:", res); // []
console.log("改变后的原数组:", arr); // ['Tom', 'King', 'Lucy', 'Jack', 'Jim']

// ----------- 从第8个索引开始,删除一个元素,初始索引大于数组长度,不删除
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(8, 1);
console.log("被删掉的元素:", res); // []
console.log("改变后的原数组:", arr); // ['Tom', 'King', 'Lucy', 'Jack', 'Jim']

// ----------- 从索引为1的位置开始删除0个元素,并插入一个元素
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(1, 0, "add");
console.log("被删掉的元素:", res); // []
console.log("改变后的原数组:", arr); // ['Tom', 'add', 'King', 'Lucy', 'Jack', 'Jim']

// ----------- 从索引为1的位置开始,删除一个元素,并插入一个元素
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(1, 1, "add");
console.log("被删掉的元素:", res); // ['King']
console.log("改变后的原数组:", arr); // ['Tom', 'add', 'Lucy', 'Jack', 'Jim']

// --------- 从索引为10的位置开始,删除一个元素,插入一个元素,数组长度没有10,删除0个,添加到末尾
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(10, 1, "add");
console.log("被删掉的元素:", res); // []
console.log("改变后的原数组:", arr); // ['Tom', 'King', 'Lucy', 'Jack', 'Jim', 'add']

// --------- 从索引为1的位置开始,删除一个,插入两个
const arr = ["Tom", "King", "Lucy", "Jack", "Jim"];
const res = arr.splice(1, 1, "add", "second");
console.log("被删掉的元素:", res); // ['King']
console.log("改变后的原数组:", arr); // ['Tom', 'add', 'second', 'Lucy', 'Jack', 'Jim']

Array.prototype.toString()

toString()将指定数组及其元素返回为一个字符串

const arr = [1, 2, "a", null, undefined, true, { name: "Tom" }];
const res = arr.toString();
console.log(res); // 1,2,a,,,true,[object Object]

Array.prototype.unshift()

unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度,该方法会改变原数组

const arr = [1, 2, 3];
const res = arr.unshift(-2, -1, 0);
console.log(res); // 6
console.log(arr); // [-2, -1, 0, 1, 2, 3]

可能很少使用到的对象方法

Object.defineProperty()

Object.defineProperty() 方法在一个对象上定义一个新属性,或者修改该对象的现有属性,并返回此对象

const tar = { a: 1, b: 2 };
const res = Object.defineProperty(tar, "d", {
  value: 99,
});
console.log("result", res); // {a: 1, b: 2, d: 99}
console.log("source", tar); // {a: 1, b: 2, d: 99}

// Object.defineProperties() 方法和 Object.defineProperty()类似,不过是可以同时定义多个
const tar = { a: 1, b: 2 };
const res = Object.defineProperties(tar, {
  d: {
    value: 99,
  },
  e: {
    value: 100,
  },
});
console.log("result", res); // {a: 1, b: 2, d: 99, e: 100}
console.log("source", tar); // {a: 1, b: 2, d: 99, e: 100}

Object.freeze()

Object.freeze()方法可以冻结一个对象。被冻结的对象不能被修改;不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,不能修改已有属性的值。此外,该对象的原型也不能被修改

const tar = { a: 1, b: 2 };
Object.freeze(tar);
tar.b = 10;
console.log("source", tar); // TypeError: Cannot assign to read only property 'b' of object '#<Object>'

Object.fromEntries()

Object.fromEntries() 方法把键值对列表转换为一个对象

const enArr = new Map([
  ["name", "King"],
  ["age", "19"],
]);
const res = Object.fromEntries(enArr);
console.log(res); // {name: 'King', age: '19'} 返回一个新对象
console.log(enArr); // Map(2) {'name' => 'King', 'age' => '19'}

Object.getOwnPropertyDescriptor()

Object.getOwnPropertyDescriptor() 方法返回指定对象自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

const tar = { a: 1, b: 2 };
const res = Object.getOwnPropertyDescriptor(tar, "a");

console.log("result", res); // {value: 1, writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptors() 方法用来获取对象的所有自身属性的描述符

const tar = { a: 1, b: 2 };
const res = Object.getOwnPropertyDescriptors(tar);

console.log("result", res); // {a: {value: 1, writable: true, enumerable: true, configurable: true},b: {value: 2, writable: true, enumerable: true, configurable: true}}

Object.prototype.hasOwnProperty()

hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(是否有指定的键)

const tar = { a: 1, b: 2 };
const res1 = tar.hasOwnProperty("b");
const res2 = tar.hasOwnProperty("c");

console.log("result", res1); // true
console.log("result", res2); // false

Object.is()

Object.is() 方法判断两个值是否相等
相等的比较如下:

  • 都是 undefined
  • 都是 null
  • 都是 Boolean
  • 都是相同对象(同一个引用对象)
  • 同一个字符或字符串
  • 同一个数字
  • 同一个数字为+0 或-0
  • 都是 NaN
const res1 = Object.is(+0, -0);
console.log(res1); // false

const res2 = Object.is(null, undefined);
console.log(res2); // false

const res3 = Object.is({ a: 1 }, { a: 1 });
console.log(res3); // false

const obj = { e: 5 };
const ob1 = obj;
const ob2 = obj;
const res4 = Object.is(ob1, ob2);
console.log(res4); // true

Object.isExtensible()

Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以给它添加新的属性)

// 默认情况下,对象都是可扩展的
const tar = { a: 1, b: 2 };
const res = Object.isExtensible(tar);
console.log("source", res); // true

// 冻结对象不可扩展
const tar = { a: 1, b: 2 };
Object.freeze(tar);
const res = Object.isExtensible(tar);
console.log("source", res); // false

// 密封对象不可扩展
const tar = { a: 1, b: 2 };
Object.seal(tar);
const res = Object.isExtensible(tar);
console.log("source", res); // false

// 阻止扩展的对象不可扩展
const tar = { a: 1, b: 2 };
Object.preventExtensions(tar);
const res = Object.isExtensible(tar);
console.log("source", res); // false

Object.isFrozen()

Object.isFrozen()方法判断一个对象是否被冻结

// 对象通常默认非冻结
const tar = { a: 1, b: 2 };
const res = Object.isFrozen(tar);
console.log("source", res); // false

Object.isSealed()

Object.isSealed() 判断一个对象是否被密封
一个对象是冻结的是指它不可扩展,所有属性不可配置的,所有数据属性(即没有 getter 或 setter 组件的访问器的属性)不可写

// 新对象通常默认是非冻结的
const tar = { a: 1, b: 2 };
const res = Object.isSealed(tar);
console.log("source", res); // false

Object.keys()

Object.keys() 方法返回一个由一个给定对象的自身可枚举属性组成的数组

const tar = { a: 1, b: 2 };
const res = Object.keys(tar);
console.log("source", res); // ['a', 'b']

// 数组的遍历属性枚举
const arrTar = ["a", "b", "c"];
const res = Object.keys(arrTar);
console.log("source", res); // ['0', '1', '2']

Object.preventExtensions()

Object.preventExtensions()方法让一个对象变的不可扩展,也就是不能再添加新的属性
Object.preventExtensions()仅阻止添加自身的属性。但其对象类型的原型依然可以添加新的属性
不可扩展对象的属性可能仍然可被删除。尝试将新属性添加到不可扩展对象将静默失败或抛出 TypeError
一旦将对象变为不可扩展的对象,就再也不能使其可扩展

const tar = { a: 1, b: 2 };
const res = Object.preventExtensions(tar);
try {
  Object.defineProperties(tar, {
    d: {
      value: 90,
    },
  });
} catch (error) {
  console.log("source", res); // {a: 1, b: 2} 并没有添加上
}

Object.seal()

Object.seal() 方法密封一个对象,阻止添加新属性并将所有现有属性标记为不可配置
密封对象是指那些不可扩展的,所有自身属性不可配置且因此不可删除(但不一定是不可写)的对象

const tar = { a: 1, b: 2 };
Object.defineProperty(tar, "b", {
  writable: false, // 属性b被设为不可写
});
const res = Object.seal(tar); // 密封该对象
try {
  tar.a = 99; // 尝试改变a的值
  tar.b = 55; // 尝试改变b的值
  Object.defineProperties(tar, {
    d: {
      value: 90, // 尝试添加新属性
    },
  });
  console.log("source1", res); // 未执行
} catch (error) {
  console.log("source", res); // {a: 99, b: 2}  a可以被改变,b不可被改变,未写入新属性
}
// 密封后的对象状态被限制在密封之前的配置

Object.values()

Object.values()方法返回给定对象自身的所有可枚举属性值的数组

const tar = { a: 1, b: 2, c: 66 };
const res = Object.values(tar);
console.log("source", res); // [1, 2, 66]

git 命令别名配置

git config --global alias.ps push

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值