【问题标题】:How to get 'this' value of caller function?如何获取调用者函数的“this”值?
【发布时间】:2011-06-13 14:46:47
【问题描述】:

如果我有这样的功能:

function foo(_this) {
    console.log(_this);
}

function bar() {}
bar.prototype.func = function() {
    foo(this);
}

var test = new bar();
test.func();

然后记录bartest 实例。

但是,要使其正常工作,我必须在 bar.prototype.func 函数中传递 this。我想知道是否有可能在不传递this 的情况下获得相同的this 值。

我尝试使用 arguments.callee.caller,但这会返回原型函数本身,而不是原型函数内的 this 值。

是否可以通过仅在原型函数中调用foo() 来记录bartest 实例?

【问题讨论】:

  • 不,您不能访问调用堆栈上的函数上下文。你必须传递这个上下文。
  • 如果您已经要创建一个特殊用途的函数来记录附加到 bar 的原型,您是否有不想传递 this 的原因?除了学习目的之外,还有其他原因使用此模式吗?
  • @TNi:不一定有实际用途,但在我的场景中会很有用。我试图通过将一个函数和边界传递给一个函数来创建一个多级 for 循环,该函数像使用 for 循环一样执行该函数。在常规的 for 循环中,可以访问 this,但这样看来我需要将 this 传递给我的函数。
  • 我认为您的原始方法是正确的。最佳做法是将对象的实例传递给全局函数。
  • 是的,它可能有实际用途。有时你不会选择 JS 如何调用函数(回调、内部等)。

标签: javascript function scope this


【解决方案1】:

如果问题是“没有通过(以任何方式)”,那么答案是

值可以通过其他方法传递。例如使用 全局变量(在 Bar 类中) 或会话或 cookie。

    function bar() {

      var myThis;

      function foo() {
          console.log(myThis);
      }

      bar.prototype.func = function() {

          myThis = this;
           foo();
      }
   }

   var test = new bar();
   test.func();

【讨论】:

  • 你还在通过this。我发现 foo.apply(this) 更干净/不那么骇人听闻。
  • 我不是在传递它,而是将值设置为在 Bar 类的命名空间内可访问的变量。这是一个很好且正确的方法。
  • @Raynos:没错,但我接受了,因为说这是不可能的。这基本上回答了我的问题。
  • @DmitriyNaurnov 您没有通过函数参数传递它,而是通过 bar 本地范围传递它,这是一个 hack
  • @Raynos:我不同意。我建议你阅读关于什么叫做 hack 的维基百科;)主题已关闭。
【解决方案2】:

我认为在bar 的上下文中调用foo 应该可以:

function foo() {
    console.log(this.testVal);
}

function bar() { this.testVal = 'From bar with love'; }
bar.prototype.func = function() {
    foo.call(this);
}

var test = new bar();
test.func(); //=> 'From bar with love'

【讨论】:

  • 谢谢,但我仍然需要传递 this 值。我的意思是我应该能够在foo 中获得this,只需在func 中调用foo()
  • 但是呃,这就是这里发生的事情,还是我误解了你的问题?在我的回答中调用 foo 使 this 从实例 test 可用于 foo,正如通过 log 记录它的 testVal 属性所证明的那样。
  • 我很抱歉不清楚。我的意思是在foo 内获得functhis 而没有 实际上在func 中传递this
  • 好吧,我真的不明白它的用途,但是,嘿。实际上foo.call(this) 并没有pass this(如您所见,foo 没有参数,什么都没有传递),而是设置了@987654340 的context @ to this,是bar构造函数创建的实例
【解决方案3】:

这个呢?

"use strict";
var o = {
    foo : function() {
        console.log(this);
    }
}

function bar() {}
bar.prototype = o;
bar.prototype.constructor = bar;
bar.prototype.func = function() {
    this.foo();
}

var test = new bar();
test.func();

或者这个:

"use strict";
Function.prototype.extender = function( o ){
    if(typeof o ==  'object'){
        this.prototype = o;
    }else if ( typeof o ==  'function' ) {
        this.prototype = Object.create(o.prototype);
    }else{
        throw Error('Error while extending '+this.name);
    }
    this.prototype.constructor = this;
}
var o = {
    foo : function() {
        console.log(this);
    }
}

function bar() {}
bar.extender(o);
bar.prototype.func = function() {
    this.foo();
}

var test = new bar();
test.func();

【讨论】:

    【解决方案4】:

    你可以在不改变外部函数的情况下做到这一点,但你必须改变你调用它的方式。

    您无法获取调用者的上下文,但您可以在使用方法applycall 调用的函数上设置this 属性。有关this 的解释,请参阅this reference

    function foo()
    {
        console.log( this );
    }
    
    function bar()
    {
        bar.prototype.func = function func() 
        {
            foo.apply( this );
        };
    }
    
    var test = new bar();
    test.func();
    

    通常如果使用this,它是在面向对象的上下文中。试图用另一个对象调用一个对象的方法,这可能表明设计不佳。多解释一下您要为更适用的设计模式实现的目标。

    有关 javascript OOP 范例的示例,请查看 my answer here

    【讨论】:

      猜你喜欢
      • 2011-08-23
      • 1970-01-01
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 1970-01-01
      • 2019-09-07
      相关资源
      最近更新 更多