Javascript / jsLint:当使用“use strict”时,用什么替换jQuery(this);

当我使用jslintvalidation以下代码时,我收到以下错误。

function displayMegaDropDown() { "use strict"; var liMegaPosition, divMegaOffset; liMegaPosition = jQuery(this).position(); divMegaOffset = { top: liMegaPosition.top + jQuery(this).height(), left: liMegaPosition.left }; jQuery(this).find("div").offset(divMegaOffset); jQuery(this).addClass("hovering"); } 

第4行第29个问题:严格违规。

  liMegaPosition = jQuery(this).position(); 

第5行第56个问题:严格违规。

 divMegaOffset = { top: liMegaPosition.top + jQuery(this).height(), left: liM... 

第6行第12个问题:严格违规。

 jQuery(this).find("div").offset(divMegaOffset); 

第8行问题12:严格违规。

 jQuery(this).addClass("hovering"); 

我猜这是因为使用了jQuery(这个),但我不明白要用什么替换它。 请注意,这不是因为jQuery未声明为全局。

我认为问题在于你不是在方法中使用this 。 以下代码

 /*global jQuery */ var myObj = { myNethod: function displayMegaDropDown() { "use strict"; var ts = jQuery(this), liMegaPosition = ts.position(), divMegaOffset = { top: liMegaPosition.top + ts.height(), left: liMegaPosition.left }; ts.find("div").offset(divMegaOffset); ts.addClass("hovering"); } }; 

或者这个

 /*global jQuery */ function displayMegaDropDown(t) { "use strict"; var ts = jQuery(t), liMegaPosition = ts.position(), divMegaOffset = { top: liMegaPosition.top + ts.height(), left: liMegaPosition.left }; ts.find("div").offset(divMegaOffset); ts.addClass("hovering"); } 

不会给你任何错误或警告。

更新 :另一个版本,非常接近原始版本,也没有错误或警告:

 /*global jQuery */ var displayMegaDropDown = function () { "use strict"; var ts = jQuery(this), liMegaPosition = ts.position(), divMegaOffset = { top: liMegaPosition.top + ts.height(), left: liMegaPosition.left }; ts.find("div").offset(divMegaOffset); ts.addClass("hovering"); }; 

更新2 :我发现这个问题对理解很有意义。 所以我看一下ECMAScript标准 。 我在“附件C(资料性)ECMAScript的严格模式”中找到以下内容(请参阅HTML版本更好):

如果在严格模式代码中对此进行评估,则不会将此值强制转换为对象。 nullundefined值不会转换为全局对象,并且原始值不会转换为包装器对象。 通过函数调用传递的值(包括使用Function.prototype.applyFunction.prototype.call进行的调用)不会强制将传递的值传递给对象(10.4.3,11.1.1,15.3.4.3,15.3。 4.4)。

我想这是JSLint错误的原因。

因为如果您关闭严格模式,代码将不再有错误:

 /*global jQuery */ /*jslint sloppy: true */ function displayMegaDropDown() { var ts = jQuery(this), liMegaPosition = ts.position(), divMegaOffset = { top: liMegaPosition.top + ts.height(), left: liMegaPosition.left }; ts.find("div").offset(divMegaOffset); ts.addClass("hovering"); } 

更新3:似乎在函数语句中不可能使用this以及在函数表达式中使用它的可能性似乎被许多人怀疑。 今天我又收到了一条评论。 所以我创建了非常简单的演示

 /*jslint devel: true */ (function () { 'use strict'; function test() { alert(this); } test(); }()); 

您可以在IE9中测试它在IE9中的演示显示警告,文本“[对象窗口]”,在当前版本的Chrome和Firefox上,您将看到“未定义”。

所以在函数语句中使用this的问题不是“jslint事情”。 这是您在开发JavaScript程序时应该考虑的真正问题。

我个人更喜欢使用函数表达式 ,几乎从不使用更多的函数语句 。 我认为来自其他程序语言的人(比如我)也会尝试使用与您最喜欢的语言相同的结构。 只有在后来才发现块中变量的定义是错误的(JavaScript中没有块级范围),并且函数语句也不总是最佳选择。

您的代码中没有严格的模式违规。 如果有,你会得到某种错误。

通过本机javascript,如果函数包含它,它将在strict mode undefined

  • 作为对象的方法
  • 通过Function.callFunction.apply
  • 作为构造函数

这就是jshint抱怨它的原因。

但是,如果该函数被用作jQuery的事件处理程序,jQuery将强制$(this)作为触发事件的DOM的jQuery对象。

要certificate这一点,请打开此页面的控制台并运行以下代码。

 (function(){ "use strict"; function event_handler() { $(this).css('background','red'); } $('#content').on('click', 'table', event_handler); })(); 

单击此页面的任何问题或答案,您将看到背景变为红色。

更容易! 只需使用ev.currentTarget而不是这个。 它与您使用===进行测试的情况相同

 function event_handler(ev) { //var $el = $(this); // jshint - error var $el = $(ev.currentTarget); // is exactly the same as above }