稀奇古怪的面试题系列
# (a == 1 && a == 2 && a == 3) 有可能是 true 吗?
# defineProperty
var val = 0;
Object.defineProperty(window, 'a', { // 这里要window,这样的话下面才能直接使用a变量去 ==
get: function () {
return ++val;
}
});
console.log(a == 1 && a == 2 && a == 3) // true
1
2
3
4
5
6
7
2
3
4
5
6
7
# 对象类型转换
当两个类型不同时进行==比较时,会将一个类型转为另一个类型,然后再进行比较。 比如Object类型与Number类型进行比较时,Object类型会转换为Number类型。 Object转换为Number时,会尝试调用Object.valueOf()和Object.toString()来获取对应的数字基本类型。
var a = {
i: 1,
toString: function () {
return a.i++;
}
}
console.log(a == 1 && a == 2 && a == 3) // true
1
2
3
4
5
6
7
2
3
4
5
6
7
# 数组类型转换
与上面这个类型转换一样,数组调用toString()会隐含调用Array.join()方法 而数组shift方法的用法:shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。如果数组是空的,那么 shift() 方法将不进行任何操作,返回 undefined 值。请注意,该方法不创建新数组,而是直接修改原有的 数组。 所以我们可以看到 a == 1时会调用toString(),toString()调用join(),join()等于shift,则转换为Number类型后为1.
var a = [1, 2, 3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3); // true
1
2
3
2
3
# 原型链的题目(getName)
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 非匿名自执行函数
var b = 10;
(function b(){
b = 20;
console.log(b);
})();
1
2
3
4
5
2
3
4
5
打印结果
ƒ b() {
b = 20;
console.log(b)
}
1
2
3
4
2
3
4
特性:
- 声明提前:一个声明在函数体内都是可见的,函数声明优先于变量声明;
- 在非匿名自执行函数中,函数变量为只读状态无法修改;
# 函数声明提升
function fn(a) { //二、形参是a,值为undefined
console.log(a); // function() {}
var a = 123; //二、a变量声明,AO里已经有了,覆盖后还是一样的
console.log(a); // 123
function a() {}// 四、a 申明为一个函数
console.log(a); // 123
var b = function() {} //二、变量b声明,值为undefined
console.log(b); // function() {}
function d() {} // 四、d声明为一个函数
var d = a //二、变量d声明,值为undefined
console.log(d); // 123
}
fn(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 匿名自执行函数中的 this
- 函数表达式,等同于普通函数或者事件绑定等机制
- 自执行函数:一般是windows/undefined
- 回调函数:一般是window/undefined,但是如果另外函数执行中,堆回调函数做了特殊处理,以自己处理的为主
- 括号表达式:小括号中包含"多项",这样也只取最后一项,但是this受到影响(一般是window/undefined)
var x = 3,
obj = {x: 5};
obj.fn = (function () {
this.x *= ++x;
return function (y) {
this.x *= (++x)+y;
console.log(x);
}
})();
var fn = obj.fn;
obj.fn(6); // x->13
fn(4); // x->234
console.log(obj.x, x); // obj.x=95 x=234
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 如何找到是谁阻止了冒泡
经常用于寻找我绑定的事件为什么没有被触发,主要是利用了 console.trace()
来显示当前执行的代码在堆栈中的调用路径。
var tmpStopPropagation = MouseEvent.prototype.stopPropagation;
MouseEvent.prototype.stopPropagation = function(...args) {
console.trace('stopPropagation');
tmpStopPropagation.call(this, ...args);
};
1
2
3
4
5
6
2
3
4
5
6
最近更新时间: 2022/09/28 16:26:36
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00