疑问1: var name = "Mac";
var showName = {
name: "Tom",
showName: function () {
alert(this.name);
},
waitShowName: function () {
//setTimeout(this.showName, 10); //结果:Mac,不能理解
this.showName(); //this为当前对象,即:Tom。 --预料中结果
}
};
showName.waitShowName();
疑问2: var name = "Mac";
var Bob = {
name: "Bob",
showName: function () {
alert(this.name);
}
}; var Tom = {
name: "Tom",
showName: function () {
var fun = Bob.showName;
fun(); //结果:Mac。 --不能理解this指的是哪个对象
//Bob.showName(); this为当前对象,结果:Bob。 --预料中结果
//alert(this.name); this为当前对象,结果:Tom。 --预料中结果
}
};
Tom.showName();
var showName = {
name: "Tom",
showName: function () {
alert(this.name);
},
waitShowName: function () {
//setTimeout(this.showName, 10); //结果:Mac,不能理解
this.showName(); //this为当前对象,即:Tom。 --预料中结果
}
};
showName.waitShowName();
疑问2: var name = "Mac";
var Bob = {
name: "Bob",
showName: function () {
alert(this.name);
}
}; var Tom = {
name: "Tom",
showName: function () {
var fun = Bob.showName;
fun(); //结果:Mac。 --不能理解this指的是哪个对象
//Bob.showName(); this为当前对象,结果:Bob。 --预料中结果
//alert(this.name); this为当前对象,结果:Tom。 --预料中结果
}
};
Tom.showName();
name: "Bob",
showName: function () {
alert(this==window);//加一句话在这里 alert(this.name);
}
};
var showName = {
name: "Tom",
showName: function () {
alert(this.name);
},
waitShowName: function () {
//setTimeout(this.showName, 10); //setTimeout后已经改变执行showName的作用域为window了,而不是showName
var me = this;//作闭包,好在setTimeout中调用
setTimeout(function () {/*不能this.showName,因为这个函数的作用域已经是window了,没有showName函数*/ me.showName(); }, 10);
this.showName(); //this为当前对象,即:Tom。 --预料中结果
}
};
showName.waitShowName(); var name = "Mac";
var Bob = {
name: "Bob",
showName: function () {
alert(this.name);
}
}; var Tom = {
name: "Tom",
showName: function () {
var fun = Bob.showName; //这样只是得到函数的句柄,就是一个函数体而已,作用域已经变为window
fun(); //结果:Mac。 --不能理解this指的是哪个对象
fun.apply(Bob);//更改作用域为Bob,会输出Bob
//Bob.showName(); this为当前对象,结果:Bob。 --预料中结果
//alert(this.name); this为当前对象,结果:Tom。 --预料中结果
}
};
Tom.showName();
根本:setTimeout方法,该方法是当前window对象的方法
window对象:Window 对象表示一个浏览器窗口或一个框架。
在客户端 JavaScript 中,Window 对象是全局对象,所有的表达式都在当前的环境中计算。也就是说,要引用当前窗口根本不需要特殊的语法,可以把那个窗口的属性作为全局变量来使用。例如,可以只写 document,而不必写 window.document。
同样,可以把当前窗口对象的方法当作函数来使用,如只写 alert(),而不必写 Window.alert()。即setTimeout==window.setTimeout。
所以在所有setTimeout方法内,最外层的this都指向window。
------------------------------------------------------------------------------------------------
疑问二:
var fun = Bob.showName;
fun为一个函数,fun=function () {alert(this.name);}
fun(); 单纯地执行一个函数,不再像调用对象方法,this指向当前函数执行环境网上搜索的第一个有效作用域,为window。例子:
var a=function(){alert(this)};
a();
var Bob = {
name: "Bob",
showName: function () {
alert(this.name);
}
}; var Tom = {
name: "Tom",
showName: function () {
var fun = Bob.showName;
fun(); //这个fun()是由window调用的,所以他会去找window.name,那就是最上面声明的 var name = "Mac"; 其实可以这么写window.fun(). }
};
Tom.showName();
比如调用一个对象的某个方法,那么方法里最外层this指向的是该对象,类似疑问二中的代码,虽然说最终this指向window,但方法fun并不是window的方法。建议不用谁调用来区分this,像call apply类似的方法用"谁调用"来理解貌似不合适,最好是看this最终指向的是那个对象。call apply方法就改变了函数执行时this的指向。PS:都是个人理解,当然,说call apply导致当前调用方法的对象已经改变也可以,只是好像有点麻烦。