Map 是Object的一个子类,可以有序保存任意类型的数据,使用键值对去存储,其中键可以存储任意类型,通过const m = new Map();即可得到一个map实例。 访问 map: 通过map.get(key)方法去属性, 不存在则返回undefined object: 通过obj.a或者obj[‘a’]去访问一个属性, 不存在则返回undefined。
赋值
Map 通过map.set去设置一个值,key可以是任意类型
Object 通过object.a = 1或者object[‘a’] = 1,去赋值,key只能是字符串,数字或symbol
删除
Map 通过map.delete去删除一个值,试图删除一个不存在的属性会返回false
Object 通过delete操作符才能删除对象的一个属性,诡异的是,即使对象不存在该属性,删除也返回true,当然可以通过Reflect.deleteProperty(target, prop) 删除不存在的属性还是会返回true。 var obj = {}; // undefined delete obj.a // true
大小
Map 通过map.size即可快速获取到内部元素的总个数
Object 需要通过Object.keys的转换才能将其转换为数组,再通过数组的length方法去获得或者使用Reflect.ownKeys(obj)也可以获取到keys的集合
迭代
Map 拥有迭代器,可以通过for-of forEach去直接迭代元素,切遍历顺序是确定的
Object 并没有实现迭代器,需要自行实现,不实现只能通过for-in循环去迭代,遍历顺序是不确定的 使用场景 如果只需要简单的存储key-value的数据,并且key不需要存储复杂类型的,直接用对象。如果该对象必须通过JSON转换的,则只能用对象,目前暂不支持Map。
map的阅读性更好,所有操作都是通过api形式去调用,更有编程体验
4. cookie 的有效时间设置为 0 会怎么样
Cookie过期时间设置为0,表示跟随系统默认,其销毁与Session销毁时间相同,即都在浏览器关闭后的特定时间删除。如果我们写程序的时候不设置Cookie的有效时间,那么,Cookie的有效时间等效于会话时间。
5. const声明了数组,还能push元素吗,为什么?
可以。数组是引用类型,const声明的引用类型变量,不可以变的是变量引用始终指向某个对象,不能指向其他对象,但是所指向的某个对象本身是可以变的。
6. 如何区分数组和对象?
方法1 :通过 ES6 中的 Array.isArray 来识别
console.log(Array.isArray([]))//true
console.log(Array.isArray({}))//false
方法2 :通过 instanceof 来识别
console.log([] instanceof Array)//true
console.log({} instanceof Array)//false
方法3 :通过调用 constructor 来识别
console.log([].constructor)//[Function:Array]
console.log({}.constructor)//[Function: Object]
方法4 :通过 Object.prototype.toString.call 方法来识别
console.log(Object.prototype.toString.call([]))//[object Array]
console.log(Object.prototype.toString.call({}))//[object Object]
7. 给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡,说下会执行几次事件,然后会先执行冒泡还是捕获?
addEventListener绑定几次就执行几次。先捕获,后冒泡
8. 请简述 == 的机制
undefined == null,结果是true。且它俩与所有其他值比较的结果都是false。 String == Boolean,需要两个操作数同时转为Number。 String/Boolean == Number,需要String/Boolean转为Number。 Object == Primitive,需要Object转为Primitive(具体通过valueOf和toString方法)。
9. 写一个 repeat 方法,实现字符串的复制拼接
方法一:之所以创建一个带 length 属性的对象,是因为要调用数组的原型方法,需要指定 call 第一个参数为类数组对象。利用闭包缓存 join,避免重复创建对象、寻找方法。
var repeat = (function () {
var join = Array.prototype.join, obj = {};
return function(target, n) {
obj.length = n + 1;
return join.call(obj, target);
};
})();
方法二:使用二分法,减少操作次数
function repeat(target, n) {
if (n === 1) {
return target;
}
var s = repeat(target, Math.floor(n / 2));
s += s;
if (n % 2) {
s += target;
}
return s;
}
后话
对于面试,说几句个人观点。
面试,说到底是一种考试。正如我们一直批判应试教育脱离教育的本质,为了面试学习技术也脱离了技术的初心。但考试对于人才选拔的有效性是毋庸置疑的,几千年来一直如此。除非你有实力向公司证明你足够优秀,否则,还是得乖乖准备面试。这也并不妨碍你在通过面试之后按自己的方式学习。
其实在面试准备阶段,个人的收获是很大的,我也认为这是一种不错的学习方式。首先,面试问题大部分基础而且深入,这些是平时工作的基础。就好像我们之前一直不明白学习语文的意义,但它的意义就在每天的谈话间。
所谓面试造火箭,工作拧螺丝。面试往往有更高的要求,也迫使我们更专心更深入地去学习一些知识,也何尝不是一种好事。