《this》

119 阅读1分钟

有关this的面试题,大部分是考察一个函数里用了this,然后调用这个函数,判断this是什么。

不要用脑子想!!!一定要把函数的调用改写成.call的形式,看this到底是什么

题1

var a = {
    name:"里边的 name",
    sayName:function(){
        console.log("this.name = " + this.name);
    }
};
var name = " 外边的name";   //用var声明的,就是全局的,等价于window.
function sayName(){
    var sss = a.sayName;
    sss();              //this.name = ?
    a.sayName();        //this.name = ?
    (a.sayName)();      //this.name = ?
    (b = a.sayName)();  //this.name = ?
}
sayName();

函数调用:sayName(); 看见函数调用,改写成.call形式 => sayName.call() 由于没传参数,所以函数sayName里如果用了this,this就是undefined,就自动是window。

进到了sayName函数里执行:

  1. sss(); => sss.call() ,没传this,this就是undefined(window)。sss函数又是对象a里的一个函数,所以this.name就是window.name,也就是" 外边的name"
  2. a.sayName(); => a.sayName.call(a) 如果是调用一个对象里的函数,JS会自动把函数前边的对象传给this。所以this就是a。那么this.name就是a.name,也就是"里边的 name"
  3. (a.sayName)(); => (a.sayName).call(a),this是a
  4. (b = a.sayName)(); => b.call() this是window

题2

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

改写!!!

obj.method(fn, 1); => obj.method.call(obj,fn,1) method里的this是obj。

进到method里执行:

  1. fn() => fn.call() this是window ,打印:10

  2. arguments[0]();arguments=[fn,1] arguments是一个数组,在JS里,数组也是一种对象,他其实是:arguments={0:fn,1:1}

    所以,arguments[0](); 等价于 arguments.0.call(arguments) 类似于对象.函数的形式,把对象传给this。它也会把argument传给this。那么arguments.0是什么?是fn,就去调用了fn,在fn里如果使用了this,this就是arguments ,所以this.length就是arguments.length ,打印:2