loading

稀奇古怪的面试题系列

# (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

# 对象类型转换

当两个类型不同时进行==比较时,会将一个类型转为另一个类型,然后再进行比较。 比如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

# 数组类型转换

与上面这个类型转换一样,数组调用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

# 原型链的题目(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

# 非匿名自执行函数

var b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();
1
2
3
4
5

打印结果

ƒ b() {
b = 20;
console.log(b)
}
1
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

# 匿名自执行函数中的 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

# 如何找到是谁阻止了冒泡

经常用于寻找我绑定的事件为什么没有被触发,主要是利用了 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
最近更新时间: 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