直接上题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
var length = 10;
function fn(){
console.log(this.length);
};
var obj = {
length: 5,
method: function (fn){
fn();
arguments[0]();
fn.call(obj, 12);
}
};
obj.method(fn, 1);

乍一看,题目很简单,答案应该是 10 10 5,可是,正确答案应该是10 2 5。下面来分析一下:

js中主要有四种this绑定的类型,分别如下:

​ 1、默认绑定

​ 2、隐式绑定

​ 3、显示绑定

​ 4、new绑定

1、默认绑定:在什么都匹配不到的情况下,非严格模式this绑定到全局对象或者global,严格模式绑定到undefined

2、隐式绑定:方法作为对象的属性调用时,方法体中的this绑定到对象身上;

3、显示绑定:通过call或者apply调用的方法,其内部的this绑定为callapply的第一个参数;

4、new绑定:在创建对象过程中,new会使得构造函数以及原型链中的方法内部的this绑定到当前正在创建的对象身上。

回到题目身上,obj.method(fn, 1)运行之后,函数内部首先运行fn(),很明显,这个时候直接调用fn,那么fn内部的this就绑定到了window身上(或者理解成由window调用fn),所以答案是10;接下来,arguments[0]()arguments在js中属于类数组对象,具有length属性,但不具有数组的一些方法,很明显,arguments[0]()运行的就是fn(),那这个地方是由谁调用fn的呢?答案是由arguments来调用,这里fn作为arguments的内部的一部分,由arguments调用,所以此时fn内部的this就指向了arguments,而这一步中的argumentslength属性值为2,所以答案是2;最后一问,使用了call来将fn中的this显示绑定到obj身上,所以,答案就是objlength属性,结果为5。