JavaScript里关于this的疑惑
2010-3-12
几天前自己捣鼓东西,碰到一个问题:能不能通过一个函数得到此函数所在的对象?例如:
var obj = function() {
this.fn = function(){
alert(this);
}
}
function get(fn) {
fn();
}
var myObj = new obj();
get(myObj.fn)
目的是让myObj里的函数fn的this始终指向myObj
上面这样把myObj.fn传入到get并在里面运行,结果myObj.fn的this就改变了指向window
可以通过传入myObj再用call达到目的,想问的是,能否不传myObj就能达到目的
function get(fn, obj) {
fn.call(obj);
}
get(myObj.fn, myObj)
经过各方指点,知道:
1.如果此函数是实例方法,那可以通过下面这个方法先把this保存起来(via @luosheng):
var obj = function() {
var that = this;
this.fn = function(){
alert(that);
}
}
function get(fn) {
fn();
}
var myObj = new obj();
get(myObj.fn)
2.如果此函数是原型方法,就不可能实现。因为原型方法是多个实例共享的,不可能从原型方法里面得到某个特定实例的引用。
函数里的this只与如何调用此函数有关系,与定义函数的方法没关系。函数跟任何一对象没有关系,与函数定义时的scope有关系(能访问到这个scope里的变量)。只能通过传入myObj对象用call绑定函数,才能确保this指向myObj。
一个误区是,函数在哪个作用域里执行,函数里的this就指向那个作用域所在对象。实际上错了:
var obj = function() {
this.fn = function(){
alert(this);
}
}
function get(fn) {
fn();
}
var obj2 = function(){
this.get = function(fn){
alert(this)
fn();
}
}
var myObj = new obj();
var myObj2 = new obj2();
myObj.fn() //this指向myObj
get(myObj.fn) //this指向顶层window
myObj2.get(myObj.fn) //this指向顶层window
myObj.fn在get里运行和在myObj2.get里运行效果是一样的,this都是指向window。
Javascript 里的函数不管在哪里定义,如果调用时没有明确指定所属 scope,this 都会指向顶层对象。(via @rainux)
指定 scope 有三个办法,obj.method(),method.apply(obj),method.call(obj)
在任何地方直接用method()直接调用某个函数,即没有用上面三个方法明确指定所属scope,this会指向顶层对象,浏览器上即window。
简化下,这样更清楚:
var obj = function(){
this.fn = function(){
alert(this);//[object Object] fn由myObj调用,this指向myObj
var that = this;
(function(){
alert(this);//[object Window] 匿名函数无对象调用,this指向顶层对象Window
alert(that == this); //false
})()
}
}
var myObj = new obj();
myObj.fn()
最好的医生是自己,最好的药物是时间,最好的心情是宁静,最好的保健是笑脸,最好的运动是步行!