“this”在aspect.around中的验证函数中失去其价值的奇怪问题。或者,aspect.around无法按预期工作

时间:2012-08-18 02:22:38

标签: javascript dojo

注意:请注意,这不是关于在JavaScript上使用this的一般性问题。这是关于aspect.around故障(它的意思是设置呼叫的范围,它没有)。问题是:为什么aspect.around出现故障?这个问题需要你仔细阅读如何重复,并提供小提琴!

我不得不将我的应用程序碎成碎片,以使问题适合小提琴。 所以这就是:

http://jsfiddle.net/mercmobily/THtsv/1/

这是一个简单的表格,有验证:

  • 在文本框中键入内容:将调用窗口小部件的验证方法。
  • 然后按下提交按钮:验证将失败,并且将调用aspect.around以包围验证方法。
  • 那个点,尝试再次在文本框中键入任何内容:它将返回错误,因为验证程序将失败,因为“this”被设置为“window”而不是窗口小部件。

因此,一旦添加了方面,验证器就会停止工作。基本上,“this”的价值会丢失。现在:

  • aspect.around()意味着在正确的范围内运行新的验证器(显然)并且失败这样做

  • 我可以通过将对验证程序的调用更改为“return originalValidator.call(this, value);来”解决“此问题”但是,它没有回答“为什么'这个'丢失了?”

  • 如果你回溯代码,你会看到aspect.around()正在做它通常做的事情......但它必须做某事错误

所以,问题是:为什么dojo.around()出现故障,而不是将this设置为传递的对象的范围?

Merc的。

2 个答案:

答案 0 :(得分:1)

要了解您的具体要求并不容易。从你的jsFiddle,我看到这个评论,所以我试图回答你在这里提出的问题:

  // QUESTION: FIND OUT WHY WE NEED THIS "call"
  return originalValidator(value);
  // return originalValidator.call(this, value);

为了保留.call的值,您在此处需要this的原因的答案正如我在下面的this在进行函数调用时如何工作的一般说明中所述

当您在此声明中进行普通函数调用时:

  return originalValidator(value);

this的值设置回window。这就是javascript的工作原理。如果要保留该函数中this的当前值,则必须指定您希望使用this.call()或{设置.apply()的特定值{1}}致电。普通函数调用中obj.method()的值不绑定到函数。它由呼叫者设置,可以是呼叫者想要的任何内容。如果您没有指定它,那么javascript会将this设置为this,这正是代码中发生的事情。


以下是如何设置window的值的一般说明,此通用说明适用于您的具体情况。

简单的规则是this的值在javascript中的每个函数调用中重置。如果它只是一个普通的函数调用,则this被设置为全局对象(在浏览器环境中为this)。因此,任何简单的函数调用都会始终将window设置为this

如果您拨打window方法,则obj.method()将设置为指向this中的obj

如果您使用method()func.apply(a, b),则可以通过func.call(a, b)this的第一个参数的值明确控制.apply()设置的内容。有关.call().call()的详情,请参阅此MDN文档herehere

答案 1 :(得分:0)

this是当前上下文。默认情况下,它是全局对象(或严格模式下的null),当调用对象(foo.bar())上的函数时,它将设置为该对象。当使用.call().apply()来调用函数时,它被设置为传递给该函数的第一个参数。

这意味着当你进入另一个函数时,你不能假设this仍然是相同的 - 即使你在this是你想要的上下文中定义该函数。

最常见的方法是添加var self = this;,然后在内部函数中使用self而不是this - 因为self是一个普通变量,它将在函数中关闭并且不受this绑定到函数中其他内容的影响。