一道关于this的JS面试题

上题目

function getLength(){
    return this.length;
}

function foo() {
    this.length = 1;
    return (function(){
        var length = 2;
        return {
            length : function(a,b,c){
                return this.arr.length;
            },
            arr : [1,2,3,4],
            info : function(){
                return getLength.call(this.length);
            }
        }
     })();
}
    
var result = foo().info();
alert(result);
复制代码

初看题目,由于嵌套了很深,出现了很多个this,不免有些发慌。 但从头到尾看下来,按照函数执行的过程,一点一点在头脑中画出一张脉络图,问题也能迎刃而解。

小伙伴们可以自己先做一下,如果和我一样有些懵,不妨先拿起笔画张图自己梳理下流程。

其实,遇到this的问题不要慌,先记住一条"总则":

this永远指向函数执行时的上下文对象。

也就是说,看到上面代码中那么多this,先别急着看this到底是谁,跟着代码的执行,一步一步往下走,你自然就能知道this是谁了。

第一步:foo():

function foo() {
   // 函数foo直接圆括号执行,上下文是window对象,即this指向window。
    this.length = 1; // window.length = 1; 给window添加了属性length
    return (function(){
       // .....
     })();
}
复制代码

函数foo执行返回一个自执行函数,看看这个自执行函数的结果是什么:

(function(){
    var length = 2;
    // 只需要看到这里,自执行函数中没有this, 只有一个私有变量length。
    // 自执行函数返回一个对象,也就是foo()的结果就是这个对象
    return {
        length : function(a,b,c){
            return this.arr.length;
        },
        arr : [1,2,3,4],
        info : function(){
            return getLength.call(this.length);
        }
    }
})()
复制代码

第二步: foo().info():

已知foo()的结果是一个对象, 假设叫AA:

{
    length : function(a,b,c){
        return this.arr.length;
    },
    arr : [1,2,3,4],
    info : function(){
        return getLength.call(this.length);
    }
}
复制代码

那么foo().info(), 函数info中的this指向上面这个对象AA:

function info(){
    // this.length即对象AA的属性length, 是一个函数
    return getLength.call(this.length);
}
复制代码

第三步:getLength.call(this.length):

这一步相当于让函数getLength执行,并将函数内部的this指向了call的参数,即this.length:

function getLength(){
    // this指向被call修改了,指向 "this.length" 即对象AA的length属性(length是个函数)
    // 所以这里的this其实是个函数,函数的length就是形参的个数,length函数有三个形参,所以这里返回3
    return this.length;
}
复制代码

所以,

var result = foo().info();
alert(result); // 弹出3
复制代码

小结

这道题目用到this的规律其实不算多,但强调了一个点:this永远指向函数执行时的上下文对象。 所以,看题目时遇见那么多this不要慌,这时候你根本不知它是谁,只要跟着代码一步一步执行下去,终会拨云见日。

转载于:https://juejin.im/post/5ce0b55af265da1ba647bc84

你可能感兴趣的:(一道关于this的JS面试题)