有关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函数里执行:
sss();=>sss.call(),没传this,this就是undefined(window)。sss函数又是对象a里的一个函数,所以this.name就是window.name,也就是" 外边的name"a.sayName();=>a.sayName.call(a)如果是调用一个对象里的函数,JS会自动把函数前边的对象传给this。所以this就是a。那么this.name就是a.name,也就是"里边的 name"(a.sayName)();=>(a.sayName).call(a),this是a(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里执行:
-
fn()=>fn.call()this是window ,打印:10 -
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