JavaScript基础-数组/对象
1、forEach函数
// 创建一个数组
const numbers = [1, 2, 3, 4, 5];// 使用 forEach 遍历数组
numbers.forEach(function(number, index) {console.log(`索引 ${index} 的值是: ${number}`);
});
2、JS数组常用函数
推荐文章:JS数组常用方法(超级详细,含理解) push、pop、unshift、shift、splice、slice、concat、join、reverse、indexOf、sort、filter、map
- push():在数组末尾添加一个或多个元素,并返回新的数组长度。
- pop():删除并返回数组的最后一个元素。
- shift():移除并返回数组的第一个元素。
- unshift():在数组开头添加一个或多个元素,并返回新的数组长度。
- map():创建一个新数组,其结果是对调用数组中的每个元素都执行一次提供的函数。
const arr = [1, 2, 3];
const newArr = arr.map((element) => element * 2);
console.log(newArr); // 输出: [2, 4, 6]
- filter():创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
const arr = [1, 2, 3, 4, 5];
const newArr = arr.filter((element) => element > 3);
console.log(newArr); // 输出: [4, 5]
- slice():提取源数组的一部分并返回一个新数组,不会改变原数组。
const arr = [1, 2, 3, 4, 5];
const newArr = arr.slice(1, 3);
console.log(newArr); // 输出: [2, 3]
- concat:函数可将两个或多个数组合并成一个新数组。 原数组不变
const arr1 = [1, 2];
const arr2 = [3, 4];
const newArr = arr1.concat(arr2);
console.log(newArr); // 输出: [1, 2, 3, 4]
- join():把数组的所有元素连接成一个字符串,元素之间用指定的分隔符分隔。
const arr = [1, 2, 3];
const str = arr.join('-');
console.log(str); // 输出: "1-2-3"
sort()
对数组的元素进行排序,默认按照字符串的 Unicode 编码顺序排序。
const arr = [3, 1, 2];
arr.sort();
console.log(arr); // 输出: [1, 2, 3]
splice():通过删除或替换现有元素或者添加新元素来修改数组, 并以数组形式返回被修改的内容。
// 示例 1:删除元素
const fruits = ['apple', 'banana', 'cherry', 'date'];
// 从索引 1 开始删除 2 个元素
const removed = fruits.splice(1, 2);
console.log('删除元素后的数组:', fruits); // [ 'apple', 'date' ]
console.log('被删除的元素:', removed); // [ 'banana', 'cherry' ]// 示例 2:插入元素
const colors = ['red', 'blue', 'green'];
// 从索引 1 开始删除 0 个元素,并插入 'yellow'
colors.splice(1, 0, 'yellow');
console.log('插入元素后的数组:', colors); // [ 'red', 'yellow', 'blue', 'green' ]// 示例 3:替换元素
const numbers = [1, 2, 3, 4, 5];
// 从索引 2 开始删除 1 个元素,并插入 6
numbers.splice(2, 1, 6);
console.log('替换元素后的数组:', numbers); // [ 1, 2, 6, 4, 5 ]
- reduce():对数组中的每个元素执行一个reducer函数(升序执行),将其结果汇总为单个返回值。
- find():返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
- findIndex():返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
- some():测试数组中的某些元素是否至少有一个通过了由提供的函数实现的测试。
- every():测试一个数组内的所有元素是否都能通过某个指定函数的测试。
- includes():判断数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。
- reverse()
:
此函数会反转数组中元素的顺序。
2.1 创建数组
1. 创建一个长度为 n
、所有元素都为 0
的数组
Array.fill()
function createZeroArray(n) {return new Array(n).fill(0);
}// 示例
let arr = createZeroArray(5);
console.log(arr); // [0, 0, 0, 0, 0]
使用 Array.from()
function createZeroArray(n) {return Array.from({ length: n }, () => 0);
}
let arr = createZeroArray(5);
console.log(arr); // [0, 0, 0, 0, 0]
2. 创建一个二维数组
外层数组的长度为 m
,每个内层数组的长度为 n
,且所有元素都为 0
使用 Array.from()
和 fill
function create2DArray(m, n) {return Array.from({ length: m }, () => new Array(n).fill(0));
}
// 示例
let arr = create2DArray(3, 4);
console.log(arr);
使用 map()
和 fill,
这种方式与上面类似,只是用展开运算符和 map()
构造。
function create2DArray(m, n) {return [...new Array(m)].map(() => new Array(n).fill(0));
}
不要这样做:因为这样会用同一个子数组引用填充整个外层数组,修改其中一个子数组会影响所有!
new Array(m).fill(new Array(n).fill(0));
3、对象常用函数
1. Object.keys():返回一个数组,包含对象自身的 (不含继承的) 所有可枚举属性(不含Symbol属性)
const obj = {a: 1, b: 2, c: 3};
console.log(Object.keys(obj)); // 输出: ['a', 'b', 'c']
2. Object.values():返回一个包含对象自身所有可枚举属性值的数组
const obj = {a: 1, b: 2, c: 3};
console.log(Object.values(obj)); // 输出: [1, 2, 3]
3. Object.entries():返回一个给定对象自身所有可枚举属性的键值对数组。
const obj = {a: 1, b: 2, c: 3};
console.log(Object.entries(obj)); // 输出: [['a', 1], ['b', 2], ['c', 3]]
4. Object.assign():用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。浅拷贝
const target = {a: 1, b: 2};
const source = {b: 3, c: 4};
Object.assign(target, source);
console.log(target); // 输出: {a: 1, b: 3, c: 4}
5. Object.defineProperty():直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
const obj = {};
Object.defineProperty(obj, 'a', {value: 1, writable: true, enumerable: true, configurable: true});
console.log(obj.a); // 输出: 1
6. Object.defineProperties():在同一时间定义或修改多个对象的属性。
const obj = {};
Object.defineProperties(obj, {'a': {value: 1},'b': {value: 2, enumerable: true}
});
7. Object.hasOwnProperty()
用于判断一个对象是否包含特定的自身(非继承)属性。
const person = {name: 'John'
};
console.log(person.hasOwnProperty('name')); // 输出: true
console.log(person.hasOwnProperty('toString')); // 输出: false
对象的遍历
1. 使用 for...in
循环
let obj = {a: 1, b: 2, c: 3};
for (let key in obj) {if (obj.hasOwnProperty(key)) { // 确保是对象自身的属性,而非继承属性console.log(key, obj[key]);}
}
2. 使用 Object.keys()
let obj = {a: 1, b: 2, c: 3};
Object.keys(obj).forEach(function(key) {console.log(key, obj[key]);
});
// 使用 Object.entries()
let obj = {a: 1, b: 2, c: 3};
Object.entries(obj).forEach(function([key, value]) {console.log(key, value);
});
使用 Reflect.ownKeys()
Reflect.ownKeys()
可以返回对象的所有属性,包括不可枚举的属性以及符号类型(Symbol)的属性。
let person= { name: 'Alice', age: 30, city: 'New York' };
Object.defineProperty(person, 'c', {value: 3, enumerable: false});Reflect.ownKeys(person).forEach(key => {console.log(`${key}: ${person[key]}`);
});
对象属性的遍历
Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身的所有属性(不含Symbol属性,当但是包括不可枚举属性)
Object.getOwnPropertySymbols(obj)返回一个数组,包含对象自身的所有Symbol属性。
const obj = {a: 1,b: 2
};Object.defineProperty(obj, 'c', {value: 3,enumerable: false // 不可枚举属性
});const symbols = Symbol('symbolKey');
obj[symbols] = 4; // Symbol 类型属性console.log(Object.getOwnPropertyNames(obj)); // ['a', 'b', 'c']
console.log(Object.keys(obj)); // ['a', 'b']
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(symbolKey)]
二、Map
1. 初始化与基本操作
- new Map():创建一个新的
Map
对象。 - set(key, value):往
Map
里添加或更新一个键值对。 - get(key):依据键来获取对应的值,要是键不存在,就返回
undefined
。 - has(key):检查
Map
中是否存在指定的键,存在返回true
,否则返回false
。 - delete(key):删除
Map
里的某个键值对,删除成功返回true
,失败返回false
。 - clear():清空
Map
中的所有键值对。 - size:返回
Map
中键值对的数量。map.zize - [...Map]:把
Map
转换为数组。
const myMap = new Map();myMap.set('name', 'John');
myMap.set(123, [1, 2, 3]);
myMap.set(true, { isAdmin: true });console.log(myMap.get('name')); // 输出:John
console.log(myMap.has(123)); // 输出:truemyMap.delete(true);
console.log(myMap.has(true)); // 输出:falsemyMap.clear();
console.log(myMap.size); // 输出:0
2. 遍历操作
- keys():返回一个包含所有键的迭代器。
- values():返回一个包含所有值的迭代器。
- entries():返回一个包含所有键值对
[key, value]
的迭代器。 - forEach(callbackFn):对
Map
中的每个键值对执行一次回调函数。
const myMap = new Map([['a', 1],['b', 2],['c', 3]
]);// 使用 for...of 遍历键
for (const key of myMap.keys()) {console.log(key); // 依次输出:a, b, c
}// 使用 for...of 遍历值
for (const value of myMap.values()) {console.log(value); // 依次输出:1, 2, 3
}// 使用 for...of 遍历键值对
for (const [key, value] of myMap.entries()) {console.log(key, value); // 依次输出:a 1, b 2, c 3
}
// for (let [key, value] of myMap) { ... } // Map 默认迭代的是 entries// 使用 forEach
myMap.forEach((value, key) => {console.log(key, value); // 依次输出:a 1, b 2, c 3
});
3. Map与数组
3.1 Map 转换为数组
3.1.1 使用扩展运算符 [...map]
const arr = [...myMap];
3.1.2 使用 Array.from()
Array.from(map)
会将 Map
的键值对转为二维数组。效果与 扩展运算符相同。
3.2 数组转换为 Map
将 [key, value]
格式的二维数组传入 Map
构造函数即可:
const arr = [['a', 1],['b', 2],['c', 3]
];const myMap = new Map(arr);
console.log(myMap.get('a')); // 输出: 1
4.1 将 Map
转换为对象后序列化
如果 Map
的键都是字符串或可以安全转换为字符串的类型(如数字),可以将 Map
转换为普通对象再序列化为 JSON:
const myMap = new Map();
myMap.set('name', 'Alice');
myMap.set('age', 30);
myMap.set('isAdmin', true);// 将 Map 转换为普通对象
const obj = Object.fromEntries(myMap);
// 序列化为 JSON
const json = JSON.stringify(obj);console.log(json); // 输出: {"name":"Alice","age":30,"isAdmin":true}
4.2 处理非字符串键的 Map
如果 Map
的键包含非字符串类型(如对象、函数等),转换为对象时这些键会被自动转换为字符串(如 [object Object]
),导致数据丢失。此时可以将 Map
转换为数组格式:
const myMap = new Map();
myMap.set(1, 'one');
myMap.set({ id: 2 }, 'two');// 将 Map 转换为 [key, value] 数组
const arr = Array.from(myMap);// 序列化为 JSON
const json = JSON.stringify(arr);console.log(json); // 输出: [[1,"one"],[{"id":2},"two"]]
4.3. 自定义序列化函数
如果你有特殊需求,例如想以特定格式保存 Map
数据,可以通过自定义函数来实现。对于复杂结构的 Map
,可以编写自定义函数来控制序列化过程。
5. 从 JSON 反序列化为 Map
如果需要将 JSON 数据还原为 Map
,可以结合 JSON.parse()
和 Map
构造函数。
JSON.parse()
只能生成普通对象或数组。如果你的 Map
包含非字符串键,那么在转换为对象时可能会丢失信息,因此推荐使用数组形式或者自定义转换逻辑。
const json = '[{"key1":"value1"},{"key2":"value2"}]';// 解析 JSON 并转换为 Map
const map = new Map(JSON.parse(json));console.log(map.get('key1')); // 输出: value1
三、Set
1. 基本操作
new Set([iterable]):
创建一个新的 Set
对象,可以传入一个可迭代对象(如数组)来初始化。
add(value)
: 添加一个值到 Set
中,返回 Set
对象本身(支持链式调用)。
delete(value)
: 删除指定值,返回一个布尔值表示是否删除成功。
has(value): 检查 Set 中是否存在指定值,返回布尔值。
clear():清空 Set 中的所有值,无返回值。
set.size:返回 Set 对象中的元素数量。注意这是一个属性而不是方法。
2. 遍历
set.keys():返回一个新的迭代器对象,它按插入顺序包含了 Set 对象中每个元素的值。因为 Set 不区分键和值,所以这个方法实际上返回的是 Set 的元素。
for (let value of set.keys()) {console.log(value);
}
set.values():和 keys() 方法一样,因为 Set 的键和值相同。
set.entries():返回一个新的迭代器对象,它按插入顺序包含了 Set 对象中每个元素的 [value, value] 数组形式。
forEach(function(value, sameValue, set), thisArg?)
使用回调函数遍历 Set 对象中的每个元素。第二个参数(可选)用来设置执行回调函数时的 this 值。
set.forEach((value, sameValue, s) => {console.log(value);
});
3. 交集、并集、差集
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);// 并集
const union = new Set([...setA, ...setB]); // Set(4) {1, 2, 3, 4}// 交集
const intersection = new Set([...setA].filter(x => setB.has(x))); // Set(2) {2, 3}// 差集(A 有但 B 没有)
const difference = new Set([...setA].filter(x => !setB.has(x))); // Set(1) {1}
4. 注意事项
引用类型:对于对象或数组等引用类型,只有引用相同的值才被视为相同。
const obj1 = { a: 1 };
const obj2 = { a: 1 };
const set = new Set();
set.add(obj1);
set.add(obj2); // 可以添加,因为 obj1 和 obj2 引用不同
值的唯一性:Set
使用 Object.is()
比较值是否相等,NaN
被视为相同(尽管 NaN !== NaN
)。
const set = new Set();
set.add(NaN);
set.add(NaN); // 不会添加,Set 中只有一个 NaN
四、常用语法
由Python到JS转变
1. Python,enumerate、if x in word
2942. 查找包含给定字符的单词
class Solution:def findWordsContaining(self, words: List[str], x: str) -> List[int]:ans = []for i, word in enumerate(words):if x in word:ans.append(i)return ans
JS,if (words[i].includes(x))
var findWordsContaining = function(words, x) {let ans = []for(let i=0; i<words.length; i++){if (words[i].includes(x)) {ans.push(i)}}return ans
};
2. 字典操作,cnt = defaultdict(int), cnt[x] += 1
let cnt = {};function increment(x) {if (cnt[x]) {cnt[x]++;} else {cnt[x] = 1;}
}// 或者更简洁地:
cnt[x] = (cnt[x] || 0) + 1;
使用 Map(适合键类型多样的情况)
let cnt = new Map();// 增加计数
cnt.set(x, (cnt.get(x) || 0) + 1);
3、JS字符串翻转
JavaScript 中的字符串是 不可变类型,所以你不能直接修改字符串内容,只能生成新的字符串。
let word = "hello";
let reversedWord = [...word].reverse().join('') // 字符串翻转// 方法二
let str = "hello";
let reversedStr = Array.from(str).reverse().join('');
console.log(reversedStr); // 输出: "olleh"// 方法三
let str = "hello";
let reversedStr = [...str].reverse().join('');
console.log(reversedStr); // 输出: "olleh"
4、整除操作
Math.floor(cntSame[key] / 2),Python中使用 “//” 实现。
ans += Math.floor(cntSame[key] / 2); // 整除运算
向上取整
Math.ceil()