23

当我使用 jslint 验证以下代码时,出现以下错误。

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(this) 但我不明白用什么替换它。请注意,这不是因为 jQuery 没有被声明为全局的。

4

4 回答 4

20

我认为问题在于您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 标准。我在“Annex C (informative) The Strict Mode of ECMAScript”中找到了以下内容(请参阅此处的 HTML 版本更好):

如果this在严格模式代码中进行评估,则this值不会被强制转换为对象。nullundefinedthis值不会转换为全局对象,原始值也不会转换为包装器对象。通过函数调用传递的this值(包括使用Function.prototype.applyFunction.prototype.call进行的调用)不会将传递的 this 值强制传递给对象(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函数语句this中使用的不可能和在函数表达式中使用的可能性似乎对许多人来说都是怀疑的。今天,我收到了更多关于此的评论。所以我创建了非常简单的演示

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

    test();
}());

您可以在这里测试它,在 IE9 中,演示会显示带有文本“[object Window]”的警报,而在 Chrome 和 Firefox 的当前版本上,您将看到“未定义”。

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

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

于 2011-09-04T16:32:27.583 回答
2

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

于 2011-09-04T15:00:50.740 回答
1

通过本机 javascript,如果函数包含它也不会被调用,this则将undefined在:strict mode

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

这就是 jshint 抱怨它的原因。

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

为了证明这一点,请打开此页面的控制台并运行以下代码。

(function(){
    "use strict";
    function event_handler() {
        $(this).css('background','red');
    }

    $('#content').on('click', 'table', event_handler);
})();

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

于 2017-01-10T13:33:35.223 回答
1

容易多了! 只需使用 ev.currentTarget 而不是这个。它与您可以使用 === 测试的相同

function event_handler(ev) {
    //var $el = $(this); // jshint - error
    var $el = $(ev.currentTarget); // is exactly the same as above
}
于 2017-02-25T11:42:39.090 回答