三道面试题。可以说是我之前的盲区了。
1.这是我自己的面试题,很遗憾错了。也确实是我自身的盲点。废话不多说,上代码。
1 for (var i = 0; i < 4; i++) {
2 var t = setTimeout(function(i) {
3 console.log(i);
4 clearTimeout(t)
5 }, 1, i)
6 }
7
8 //会输出什么?
我自己初次看,很像常见的那种考察异步的面试题。再看,每次代码运行后都会 clear 一次的计时器。setTimeout 会传两个参数,第三个被忽略掉。
这就有一个陷阱:每次 setTimeout 都会返回一个数,每次 t 都会指向后面的计时器,因此最后一个会被 clear 。所以最后会输出三行。
然后我就以为是 4 4 4;然而答案是 0 1 2。为什么?
后来在网上搜索求证,发现 setTimeout 可以传不止两个参数。从第三个开始的参数,会在计时函数体被调用时传入。因此这里的计时函数内的 i 会被 setTimeout 传入。因此就跟如下形式一样:
1 function fn(i) {
2 console.log(i);
3 clearTimeout(t)
4 }
5 for (var i = 0; i < 4; i++) {
6 var t = setTimeout(fn.bind(null, i), 1)
7 }
就是可以保存变量的形式了。网上好像说这不是标准,是各浏览器自己的实现,然而从我的测试来看chrome,Firefox,IE11通用。
2. 类似上一题。
1 function fn2() { 2 for (var i = 0; i < 4; i++) { 3 var tc = setInterval(function(i, tc) { 4 console.log(i); 5 clearInterval(tc) 6 }, 10, i, tc); 7 } 8 }
输出什么?
这个跟上题不一样的地方是把计时器id也传进去了。答案是 0 1 2 3 3 3 3 3 ...无限循环下去了。
这里把计时器作为参数传进去,其实是在赋值前,所以传入的时候 tc 其实指向前一个计时器。所以四次制定,tc传入的东西分别是: undefined, id1, id2, id3。而 id4 就不会传入。
因此,最后一个计时器不会被清除。前面的输出 1 时会清除 0 的计时器, 输出 2 时会清除 1 的计时器...
3. 别人的分享。
1 function obj(name) { 2 ????? 3 } 4 obj.????? = 'name2'; 5 var a = obj('name1'); 6 var b = new obj; 7 // 上面问号的源码如何会有下面的输出 8 console.log(a.name) // name1 9 console.log(b.name) // name2
其实这题不难,但是第一眼很怪。这一句 var b = new obj 竟然没有括号来执行函数。
后来经过自己实验,发现在 new 命令后并不需要括号,函数一样也会执行,不过不能带参数了,从下面代码可以看出来。
1 function fn() { 2 console.log(arguments.length) // 0 3 } 4 var a = new fn; 5 console.log(a.constructor === fn) // true
这样的话这个题就好解了。
第一个问号是 return name && {name} 。如果有 name 就返回含 name 的对象。
第二个是 obj.prototype.name = 'name2' 。如果未传参,则实例上面没有 name 属性。通过查找原型对象可以找到。