Javascript基础面试题(三)- 数据结构
本文整理了Javascript基础面试题,包括数组有哪些方法会改变自身?Set和WeakSet的区别?对象和Map和WeakMap的区别?
数组有哪些方法会改变自身
shift :删除第一个元素,并返回删除的元素
unshift : 头部插入一个新的元素,返回数组的长度
pop :删除最后一个元素,并返回删除的元素
push :尾喉新增一个元素,并返回新的长度
reverse :反转数组
sort :对数组进行排序,默认排序顺序规则是将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的
[5, 3, 4, 2].sort((a, b) => a - b); // 升序
[5, 3, 4, 2].sort((a, b) => b - a); // 升序
splice : 可以是先删除,新增增,替换数组元素,返回被删除数组,无删除则返回空
[2, 3, 4].splice(0, 1); // 0位置删除一个,返回[2]
[2, 3, 4].splice(0, 1, 5); // 0位置删除1个,插入5,原数组是[5, 3, 4],返回[2]
Set 和 WeakSet 的区别
Set 是值的集合,可以用来存储任意类型的值,Set 可以按照插入的顺序来遍历输出,但是插入的值会自动去重,下面例子
let mySet = new Set();
mySet.add(1); // Set [ 1 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add(5); // Set [ 1, 5 ]
mySet.add("some text"); // Set [ 1, 5, "some text" ]
for (let item of mySet) console.log(item); // 1, 5, "some text"
tip
可以用 Set 来去重
Set 的特殊情况
- 0 和 -0 不会去重
- 虽然 NaN 不等于 NaN,但是 NaN 和 NaN 会去重,只能存储一个
WeakSet 与 Set 类似,可以自动去重,不同点如下
- WeakSet 存储的类型只能是对象的集合
- WeakSet 集合中的对象是弱引用,如果存储的对象没有被引用了,那么这个对象就会被垃圾回收机制回收,因为不可控,所以不可枚举
WeakSet 可以用来检测循环引用,通过递归调用自身的函数需要一种通过跟踪哪些对象已被处理
// 对 传入的subject对象 内部存储的所有内容执行回调
function execRecursively(fn, subject, ws = null) {
if (!ws) ws = new WeakSet();
// 避免无限递归
if (ws.has(subject)) return;
fn(subject);
if ("object" === typeof subject) {
ws.add(subject);
for (let key in subject) execRecursively(fn, subject[key], ws);
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar",
},
};
foo.bar.baz = foo; // 循环引用!
execRecursively((obj) => console.log(obj), foo);
对象和 Map 和 WeakMap 的区别
- 对象的 key 只能是字符串,Map 的 key 可以是任意对象,WeakMap 的 key 只能是对象(null 除外)
- WeakMap 不可枚举,对象和 Map 可以枚举
- Map 有
size
属性获取键值对的个数,对象和 WeakMap 无属性可以读取键值的个数
WeakMap 和 WeakSet 的 key 同样是弱引用,当相应的对象被垃圾回收机制回收的时候,key 就会被回收
const wm = new WeakMap();
let element = document.getElementsByTagName("div")[0];
wm.set(element, "1024nav.com");
console.log(wm.get(element)); // 1024nav.com
element = null;
console.log(wm.get(element)); // undefined
typeof NaN 结果是什么
NaN 表示非数字,不过 typeof NaN === 'number'
为 true