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()
最好的医生是自己,最好的药物是时间,最好的心情是宁静,最好的保健是笑脸,最好的运动是步行!