JavaScript里关于this的疑惑

发布于 2022-09-08 04:03:13 字数 3040 浏览 5 评论 0

几天前自己捣鼓东西,碰到一个问题:能不能通过一个函数得到此函数所在的对象?例如:

  1. var obj = function() {
  2.     this.fn = function(){
  3.         alert(this);
  4.     }
  5. }
  6. function get(fn) {
  7.     fn();
  8. }
  9. var myObj = new obj();
  10. get(myObj.fn)

复制代码目的是让myObj里的函数fn的this始终指向myObj
上面这样把myObj.fn传入到get并在里面运行,结果myObj.fn的this就改变了指向window
可以通过传入myObj再用call达到目的,想问的是,能否不传myObj就能达到目的

  1. function get(fn, obj) {
  2.     fn.call(obj);
  3. }
  4. get(myObj.fn, myObj)

复制代码经过各方指点,知道:
1.如果此函数是实例方法,那可以通过下面这个方法先把this保存起来(via @luosheng):

  1. var obj = function() {
  2.     var that = this;
  3.     this.fn = function(){
  4.         alert(that);
  5.     }
  6. }
  7. function get(fn) {
  8.     fn();
  9. }
  10. var myObj = new obj();
  11. get(myObj.fn)

复制代码2.如果此函数是原型方法,就不可能实现。因为原型方法是多个实例共享的,不可能从原型方法里面得到某个特定实例的引用。

函数里的this只与如何调用此函数有关系,与定义函数的方法没关系。函数跟任何一对象没有关系,与函数定义时的scope有关系(能访问到这个scope里的变量)。只能通过传入myObj对象用call绑定函数,才能确保this指向myObj。

一个误区是,函数在哪个作用域里执行,函数里的this就指向那个作用域所在对象。实际上错了:

  1. var obj = function() {
  2.     this.fn = function(){
  3.         alert(this);
  4.     }
  5. }
  6. function get(fn) {
  7.     fn();
  8. }
  9. var obj2 = function(){
  10.     this.get = function(fn){
  11.         alert(this)
  12.         fn();
  13.     }
  14. }
  15. var myObj = new obj();
  16. var myObj2 = new obj2();
  17. myObj.fn()  //this指向myObj
  18. get(myObj.fn)   //this指向顶层window
  19. 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。

简化下,这样更清楚:

  1. var obj = function(){
  2.     this.fn = function(){
  3.         alert(this);//[object Object]   fn由myObj调用,this指向myObj
  4.         var that = this;
  5.         (function(){
  6.             alert(this);//[object Window]   匿名函数无对象调用,this指向顶层对象Window
  7.             alert(that == this);   //false
  8.          })()
  9.     }
  10. }
  11. var myObj = new obj();
  12. myObj.fn()

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文