JS函数中this指向的几道面试题(有趣)

//eg:1
var length = 10;
function fn() {
    console.log(this.length);
}
var obj = {
    length: 5,
    method: function () {
    fn();
    arguments[0]();
    }
}
obj.method(fn, 1);

首先看一下语句结构:

  • 一个全局变量length = 10;
  • 一个全局函数fn();
  • 一个全局对象obj,并且obj中有

    • 1个length属性
    • 一个method方法,在这个method方法中调用了fn()arguments[0]();

分析完这个结构就要看最后的函数调用,是通过对象obj的一个方法进行调用的,这个时候就存在一个函数中的this指向问题.

obj.method中的第一个fn()函数,最终this的指向是外部的window顶级对象,那么第9行的fn()执行后会访问全局变量length返回10;

而第二步arguments[0]()是以传入的第一个参数为函数执行的>>也就是fn(),

这个时候的知识点就是:this指向 谁调用指向谁,谁最后调用指向谁;
案例中通过object对象调用method方法,最后的调用者就是method 相当于 obj.method.arguments[0]();

既然这个时候的this的指向是method方法的参数伪数组,输出arguments的参数length,也就是fn和1 总长度为2;

所以在控制台输出之后的输出结果是

10;
2;

为了进一步查看思路是否正确可以把外部的fn()修改为:

function fn() {
    console.log(this);
    console.log(this.length);
}

执行后控制台输出

Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
10
Arguments(2) [ƒ, 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]0: ƒ fn()1: 1callee: ƒ ()length: 2Symbol(Symbol.iterator): ƒ values()__proto__: Object
2

//eg:2
var b = 1;
function outer() {
    var b = 2
    function inner() {
        b++;
        var b = 3;
        console.log(b)
    }
    inner();
}
outer();

结构:

  • 一个全局变量b;
  • 一个全局函数outer();

    • 在outer()里又声明和调用了一个inner()函数

最后调用函数outer();
按照结构来看的话,其实这就一个函数内部变量提升、访问的问题,从调用了outer()之后,就从代码的第3-11行进行了编译执行,首先是第7行的局部变量b进行变量声明提升,所以在inner()函数体中的实际顺序为:

function inner(){
    var b;
    b++; //因为只有声明提升了,赋值没有提升,那么b++之后的返回结果是:undefined;
    b = 3; //重新给b赋值:b =3;
    console.log(b); //3
}
inner();

所以在控制台输出之后返回结果是:3;
在这个题里,涉及到的知识点是:

  • 函数内部变量声明提升,赋值并不提升
  • 函数内部使用的变量会优先从函数体内部进行查找,如果查找到的话即使用,如果内部查找不到才会访问外部环境进行查找

我后面会陆陆续续的丰富一些js的常用面试题,旨在分享和交流,如果有什么地方说的不太准确,欢迎各位留言评论发表意见(友善的发言会给人带来好运哦 ^ ^)


1 + 7 =

求知若飢,虛心若愚。