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()
分类:技术文章
评论

*

*

2016年3月1日 16:59

最好的医生是自己,最好的药物是时间,最好的心情是宁静,最好的保健是笑脸,最好的运动是步行!

Baidu
sogou