数组、对象以及相互转换的方法

什么是数组

数组(Array)是一种在编程中广泛使用的数据结构,用于存储和组织多个元素。在 JavaScript 中,数组是一种特殊的对象,用于存储按顺序排列的值。每个值在数组中都有一个对应的数字索引,用于访问该值

1. push

push将一个或多个元素添加到数组的末尾,并返回新数组的长度。

const array1 = [1, 2, 3];
const length = array1.push(4, 5);
// 现在 array1 为 [1, 2, 3, 4, 5],length 为 5
2. pop

push删除数组中的最后一个元素,并返回该元素的值。

const array1 = [1, 2, 3];
const lastElement = array1.pop();
// lastElement 的值为 3,array1 现在为 [1, 2]
3. shift

shift删除数组中的第一个元素,并返回该元素的值。

const array1 = [1, 2, 3];
const firstElement = array1.shift();
// firstElement 的值为 1,array1 现在为 [2, 3]
4. unshift

unshift将一个或多个元素添加到数组的开头,并返回新数组的长度。

const array1 = [1, 2, 3];
const length = array1.unshift(0);
// 现在 array1 为 [0, 1, 2, 3],length 为 4
5. slice

slice从已有的数组中返回选定的元素。

const fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
const citrus = fruits.slice(1, 3);
// citrus 为 ['Orange', 'Lemon']
6. splice

splice向/从数组中添加/删除项目,然后返回被删除的项目。

const fruits = ['Banana', 'Orange', 'Apple', 'Mango'];
fruits.splice(2, 0, 'Lemon', 'Kiwi');
// 现在 fruits 为 ['Banana', 'Orange', 'Lemon', 'Kiwi', 'Apple', 'Mango']
7. map

map创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
// 输出结果:[2, 8, 18, 32]
8. filter

filter创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
// 输出结果:['exuberant', 'destruction', 'present']
9. reduce

reduce对数组中的所有元素执行提供的 reducer 函数,并将其结果汇总为单个返回值。

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 输出结果:10
10. forEach

reduce对数组中的每个元素执行提供的函数。

const array1 = ['a', 'b', 'c'];
array1.forEach(element => console.log(element));
// 输出结果:
// 'a'
// 'b'
// 'c'
11. find

find返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
// 输出结果:12
12. findIndex

findIndex返回数组中满足提供的测试函数的第一个元素的索引。否则返回 -1。

const array1 = [5, 12, 8, 130, 44];
const foundIndex = array1.findIndex(element => element > 10);
// 输出结果:1
13. some

some检测数组中的元素是否有一个满足提供的测试函数。如果有则返回 true,否则返回 false。

const array1 = [2, 5, 8];
const even = element => element % 2 === 0;
const result = array1.some(even);
// 输出结果:true
14. every

every检测数组中所有的元素是否都满足提供的测试函数。如果是则返回 true,否则返回 false。

const array1 = [2, 4, 6, 8, 10];
const even = element => element % 2 === 0;
const result = array1.every(even);
// 输出结果:true
15. reduceRight

reduceRight 方法对数组中的每个元素执行提供的 reducer 函数(从右到左),将其结果汇总为单个返回值。

const array1 = [[0, 1], [2, 3], [4, 5]];
const flattened = array1.reduceRight((accumulator, currentValue) => accumulator.concat(currentValue), []);
// 输出结果:[4, 5, 2, 3, 0, 1]
16. flat

flat 方法创建一个新数组,其中有任何嵌套数组内的所有元素都被展平为一个新数组的元素。

const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// 输出结果:[0, 1, 2, 3, 4]
17. flatMap

flatMap 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。

const arr1 = [1, 2, 3, 4];
console.log(arr1.flatMap(x => [x * 2]));
// 输出结果:[2, 4, 6, 8]
18. copyWithin

copyWithin 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小。

const array1 = ['a', 'b', 'c', 'd', 'e'];
console.log(array1.copyWithin(0, 3, 4));
// 输出结果:['d', 'b', 'c', 'd', 'e']
19. keys

keys 方法返回一个包含数组中每个索引键的数组迭代器对象。

const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();
for (const key of iterator) {
  console.log(key);
}
// 输出结果:
// 0
// 1
// 2
20. values

values 方法返回一个包含数组中每个值的数组迭代器对象。

const array1 = ['a', 'b', 'c'];
const iterator = array1.values();
for (const value of iterator) {
  console.log(value);
}
// 输出结果:
// 'a'
// 'b'
// 'c'
21. entries

entries 方法返回一个包含数组中每个索引键值对的数组迭代器对象。

const array1 = ['a', 'b', 'c'];
const iterator = array1.entries();
for (const entry of iterator) {
  console.log(entry);
}
// 输出结果:
// [0, 'a']
// [1, 'b']
// [2, 'c']
22. from

from 方法从类数组或可迭代对象中创建一个新的数组实例。

const nameArray = Array.from('John');
// 输出结果:['J', 'o', 'h', 'n']
23. Array.of

Array.of 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。

console.log(Array.of(7));
// 输出结果:[7]
console.log(Array.of(1, 2, 3));
// 输出结果:[1, 2, 3]
24. fill

fill 方法用静态值填充一个数组中从起始索引到终止索引内的全部元素。

const array1 = [1, 2, 3, 4];
console.log(array1.fill(0, 2, 4));
// 输出结果:[1, 2, 0, 0]
25. sort

sort 方法对数组的元素进行原地排序,并返回数组。默认排序顺序是根据字符串Unicode码点。

const array1 = [1, 30, 4, 21, 100000];
console.log(array1.sort());
// 输出结果:[1, 100000, 21, 30, 4]
26. reverse

reverse 方法将数组中元素的位置颠倒,第一个数组元素成为最后一个数组元素,最后一个数组元素成为第一个。

const array1 = ['one', 'two', 'three'];
const reversed = array1.reverse();
// 输出结果:['three', 'two', 'one']
27. flatMap

flatMap 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。

const arr1 = [1, 2, 3, 4];
console.log(arr1.flatMap(x => [x * 2]));
// 输出结果:[2, 4, 6, 8]
28. toString

toString 方法返回一个表示指定数组及其元素的字符串。

const array1 = [1, 2, 'a', '1a'];
console.log(array1.toString());
// 输出结果:"1,2,a,1a"
29. Symbol.iterator

Symbol.iterator 是一个返回数组的默认迭代器的函数。 是一个 JavaScript 内置的(Symbol),它代表了一个可被调用来返回对象默认迭代器的函数。在数组中,当你希望迭代数组元素时,可以使用 Symbol.iterator。
每当需要遍历一个对象(比如数组)时,JavaScript 会寻找并调用这个对象的 Symbol.iterator 方法。这个方法返回一个迭代器对象,该对象包含一个 next() 方法,用于按顺序访问对象中的每个元素,直到最后一个元素,并通过 done 属性标识是否已经完成遍历。

const array1 = ['a', 'b', 'c'];
const iterator = array1[Symbol.iterator]();
console.log(iterator.next().value); // 输出结果:'a'
console.log(iterator.next().value); // 输出结果:'b'
console.log(iterator.next().value); // 输出结果:'c'

在这个示例中,我们获取了数组 array1 的默认迭代器,并通过调用其 next() 方法逐个访问了数组中的元素。
Symbol.iterator 提供了一种规范化的机制,使得 JavaScript 中的许多数据结构都可以被迭代,例如数组、集合、映射等。这样可以确保开发者可以使用统一的方式来处理不同类型的数据结构。

30. concat

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

const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const newArray = array1.concat(array2);
// 输出结果:['a', 'b', 'c', 'd', 'e', 'f']
31. includes

includes 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则返回 false。

const array1 = [1, 2, 3];
console.log(array1.includes(2)); // 输出结果:true
console.log(array1.includes(4)); // 输出结果:false
  1. flat
    flat 方法创建一个新数组,其所有子数组元素递归地拉平到指定深度。
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// 输出结果:[0, 1, 2, 3, 4]

对象

在JavaScript中,对象是一种数据结构,用于存储和组织数据。对象可以包含多个键值对,其中每个键值对表示一个属性(property),该属性的键(key)是一个字符串,而值(value)可以是任意类型的数据,包括其他对象、函数、数组等。对象可以被用来表示复杂的数据结构,也可以用来模拟现实世界中的实体。

在JavaScript中,对象是一种引用类型,这意味着通过引用来访问和操作对象。对象提供了一种灵活的方式来组织和管理数据,因此它们广泛应用于JavaScript编程中的各个方面,包括但不限于数据存储、应用程序状态管理、以及模块化编程中。

在 JavaScript 中,对象的方法通常分为自有方法和原型方法。以下是介绍对象方法的两种类型以及如何获取它们的方式:

自有方法

  1. Object.keys(obj):返回一个由对象自身可枚举属性组成的数组。
  2. Object.getOwnPropertyNames(obj):返回一个由对象自身所有属性(包括不可枚举属性)组成的数组。

原型方法

  1. Object.prototype.toString():返回对象的字符串表示。
  2. Object.prototype.valueOf():返回指定对象的原始值。
  3. Object.prototype.hasOwnProperty(prop):返回一个布尔值,指示对象是否具有特定属性。
  4. Object.prototype.isPrototypeOf(obj):返回一个布尔值,表示调用对象是否处于另一个指定对象的原型链上。
  5. Object.prototype.propertyIsEnumerable(prop):返回一个布尔值,指示指定的属性是否可枚举。

示例

const obj = {
  name: "Alice",
  age: 30,
  greet: function() {
    console.log("Hello!");
  }
};

// 获取对象的自有属性名
console.log(Object.keys(obj)); // ['name', 'age', 'greet']

// 检查对象是否具有特定属性
console.log(obj.hasOwnProperty('name')); // true

// 调用对象自定义的方法
obj.greet(); // 输出结果:"Hello!"

如果您想了解特定对象上可用的方法或属性,您可以使用类似 Object.keysObject.getOwnPropertyNames 这样的方法来检查对象的属性列表。对于原型方法,您可以通过访问 Object.prototype 上的方法来了解这些方法。

JavaScript 对象的其他内置方法

  • Object.freeze(obj):冻结一个对象,防止添加新属性或修改现有属性。

  • Object.seal(obj):封闭一个对象,防止添加新属性,并将所有现有属性标记为不可配置。

  • Object.isFrozen(obj):判断一个对象是否被冻结。

  • Object.isSealed(obj):判断一个对象是否被封闭。

  • Object.defineProperty(obj, prop, descriptor):定义一个新属性或修改现有属性的特性。

这些方法提供了对对象进行更深层次控制和管理的能力,使您能够确保对象的状态和行为符合预期。

示例

const obj = {
  name: "Bob",
  age: 25
};

// 冻结对象,防止修改
Object.freeze(obj);

obj.age = 30; // 由于对象已经被冻结,该操作无效

console.log(Object.isFrozen(obj)); // 输出结果:true

// 定义新属性
Object.defineProperty(obj, 'job', {
  value: 'Engineer',
  writable: false,
  enumerable: true
});

console.log(obj.job); // 输出结果:"Engineer"
  • Object.keys(obj):返回一个由给定对象的自身可枚举属性组成的数组。
  • Object.values(obj):返回一个给定对象自身的所有可枚举属性值的数组。
  • Object.entries(obj):返回一个给定对象自身可枚举属性的键值对数组。
  • Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不仅仅是可枚举属性)的名称。

这些方法提供了检索对象属性及其值的便捷方式,并可以用于迭代和处理对象的属性。

示例

const person = {
  firstName: "John",
  lastName: "Doe"
};

// 获取对象自身的所有属性名
console.log(Object.keys(person)); // 输出结果:["firstName", "lastName"]

// 获取对象自身的所有属性值
console.log(Object.values(person)); // 输出结果:["John", "Doe"]

// 获取对象自身的所有属性键值对
console.log(Object.entries(person)); // 输出结果:[["firstName", "John"], ["lastName", "Doe"]]
  • Object.prototype.hasOwnProperty(prop):返回一个布尔值,指示对象是否具有特定属性。
  • Object.prototype.isPrototypeOf(obj):返回一个布尔值,表示调用对象是否处于另一个指定对象的原型链上。
  • Object.prototype.propertyIsEnumerable(prop):返回一个布尔值,指示指定的属性是否可枚举。
  • Object.prototype.toLocaleString():返回对象的本地化字符串表示。
  • Object.prototype.isExtensible(obj):判断一个对象是否可扩展。
  • Object.prototype.preventExtensions(obj):阻止新属性添加到对象,并使所有现有属性标记为不可配置。

这些方法提供了更多的功能,包括检查对象的特性、本地化字符串表示以及管理对象的可扩展性。

示例

const car = {
  make: "Toyota",
  model: "Camry"
};

// 检查对象是否具有特定属性
console.log(car.hasOwnProperty('make')); // 输出结果:true

// 判断对象是否可扩展
console.log(Object.isExtensible(car)); // 输出结果:true

// 阻止对象扩展
Object.preventExtensions(car);
console.log(Object.isExtensible(car)); // 输出结果:false

这些方法允许您对对象进行更深入的检查和控制,确保对象的状态符合预期。

除了之前提到的方法外,JavaScript 对象还具有其他一些内置方法:

  • Object.getPrototypeOf(obj):返回指定对象的原型(__proto__)。
  • Object.setPrototypeOf(obj, prototype):设置一个指定对象的原型(即 __proto__ 的值)。
  • Object.getOwnPropertyDescriptors(obj):返回指定对象所有自身属性(非继承属性)的描述符。
  • Object.defineProperties(obj, props):定义或修改多个属性的特性。

这些方法允许进行更深入的操作,如获取和设置对象的原型,以及定义多个属性的特性。

示例

function Person(name) {
  this.name = name;
}

const person1 = new Person('Alice');

// 获取对象的原型
console.log(Object.getPrototypeOf(person1)); // 输出结果:Person {}

// 定义多个属性的特性
Object.defineProperties(person1, {
  age: {
    value: 30,
    writable: true
  },
  job: {
    value: 'Engineer',
    writable: false
  }
});

console.log(person1.age); // 输出结果:30
  • Object.getOwnPropertySymbols(obj):返回一个给定对象自身的所有 Symbol 类型的属性键的数组。
  • Object.is(value1, value2):判断两个值是否是同一个值。
  • Object.fromEntries(iterable):将键值对列表转换为一个新的对象。

这些方法提供了进一步操作对象的能力,包括处理 Symbol 类型的属性键,进行严格相等性的比较,以及从键值对列表创建新对象。

示例

const symbol1 = Symbol('key1');
const symbol2 = Symbol('key2');

const obj = {
  [symbol1]: 'value1',
  [symbol2]: 'value2'
};

// 获取对象自身的所有 Symbol 类型的属性键
console.log(Object.getOwnPropertySymbols(obj)); // 输出结果:[Symbol(key1), Symbol(key2)]

// 判断两个值是否是同一个值
console.log(Object.is(5, 5)); // 输出结果:true

// 将键值对列表转换为一个新的对象
const entries = [['name', 'John'], ['age', 30]];
const newObj = Object.fromEntries(entries);
console.log(newObj); // 输出结果:{ name: 'John', age: 30 }

这些方法提供了更多的灵活性,使您能够更好地操作对象并执行各种任务。

  • Object.entries(obj):返回一个给定对象自身可枚举属性的键值对数组。
  • Object.getOwnPropertyDescriptors(obj):返回指定对象所有自身属性(非继承属性)的描述符。
  • Object.getOwnPropertyDescriptor(obj, prop):返回指定对象上一个自有属性对应的属性描述符。
  • Object.isExtensible(obj):判断一个对象是否可扩展。
  • Object.keys(obj):返回一个由一个给定对象的自身可枚举属性组成的数组。
  • Object.preventExtensions(obj):阻止新属性添加到对象,并使所有现有属性标记为不可配置。

这些方法提供了对象属性、特性以及可扩展性方面的更多控制和管理能力。它们允许您以不同的方式操作和检查对象。

示例

const obj = {
  name: 'Alice',
  age: 30
};

// 返回指定对象自身可枚举属性的键值对数组
console.log(Object.entries(obj)); 

// 返回指定对象所有自身属性的描述符
console.log(Object.getOwnPropertyDescriptors(obj));

// 判断一个对象是否可扩展
console.log(Object.isExtensible(obj)); 

// 阻止新属性添加到对象
Object.preventExtensions(obj);

这些方法为您提供了更多的功能,用于操作对象的属性、特性以及可扩展性。

数组转对象

在 JavaScript 中,可以使用多种方法将数组转换为对象。以下是其中一些常见的方法:

  • 使用 Array.reduce 方法
const array = [['a', 1], ['b', 2], ['c', 3]];
const obj = array.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }
  • 使用 Object.fromEntries 方法(需要 ECMAScript 2019 或更新版本支持)
const array = [['a', 1], ['b', 2], ['c', 3]];
const obj = Object.fromEntries(array);
console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }
  • 使用 forEach 方法
const array = [['a', 1], ['b', 2], ['c', 3]];
let obj = {};
array.forEach(([key, value]) => {
  obj[key] = value;
});
console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }
  • 使用 for…of 循环
const array = [['a', 1], ['b', 2], ['c', 3]];
let obj = {};
for (const [key, value] of array) {
  obj[key] = value;
}
console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }

这些方法提供了将数组转换为对象的不同方式,您可以根据代码风格和需求选择合适的方法。

当涉及将数组转换为对象时,还有一些其他方法:

  • 使用 Map 对象
const array = [['a', 1], ['b', 2], ['c', 3]];
const obj = Object.fromEntries(new Map(array));
console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }

如果使用了 lodash 库,可以使用其 fromPairs 方法来实现数组向对象的转换。

const _ = require('lodash');
const array = [['a', 1], ['b', 2], ['c', 3]];
const obj = _.fromPairs(array);
console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }

这些方法提供了不同的途径来实现数组向对象的转换,您可以根据项目需求和个人偏好来选择适合的方法。

当涉及将数组转换为对象时,还有一种常见的情况是根据数组中元素的某些属性创建对象。在这种情况下,可以使用 Array.reduce 方法来实现:

  • 根据数组元素的某些属性创建对象
const array = [
  { id: 'a', value: 1 },
  { id: 'b', value: 2 },
  { id: 'c', value: 3 }
];

const obj = array.reduce((acc, item) => {
  acc[item.id] = item.value;
  return acc;
}, {});

console.log(obj);
// 输出结果:{ a: 1, b: 2, c: 3 }

这种情况下,我们使用 Array.reduce 方法根据每个元素的 id 属性创建了一个新的对象。

对象转数组

在 JavaScript 中,将对象转换为数组通常有几种常见的方法:

  • Object.keys 和 map 方法
const obj = { a: 1, b: 2, c: 3 };
const arr = Object.keys(obj).map(key => [key, obj[key]]);
console.log(arr);
// 输出结果:[ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
  • Object.entries 方法
const obj = { a: 1, b: 2, c: 3 };
const arr = Object.entries(obj);
console.log(arr);
// 输出结果:[ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
  • 手动迭代对象属性
const obj = { a: 1, b: 2, c: 3 };
const arr = [];
for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    arr.push([key, obj[key]]);
  }
}
console.log(arr);
// 输出结果:[ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
  • 使用 Object.values 方法(只提取值)
const obj = { a: 1, b: 2, c: 3 };
const arr = Object.values(obj);
console.log(arr);
// 输出结果:[ 1, 2, 3 ]

这些方法提供了多种方式来将对象转换为数组。还有一种常见的情况是将对象的值转换为数组。这种情况下,可以使用 Object.values 方法:

  • 使用 Object.values 方法(提取值)
const obj = { a: 1, b: 2, c: 3 };
const arr = Object.values(obj);
console.log(arr);
// 输出结果:[ 1, 2, 3 ]

这个方法适用于您只需要对象中的值而不需要键的情况。

以上是一些将对象转换为数组的常见方法。如果您需要更多帮助或有其他问题,请随时告诉我。我很乐意继续帮助您!