跳到主内容

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