Javascript/jsLint: What to replace jQuery(this) with when using “use strict”;

强颜欢笑 提交于 2019-12-08 14:30:11

问题


When I validate the following code with jslint I get the following errors.

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");
}

Problem at line 4 character 29: Strict violation.

 liMegaPosition = jQuery(this).position();  

Problem at line 5 character 56: Strict violation.

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

Problem at line 6 character 12: Strict violation.

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

Problem at line 8 character 12: Strict violation.

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

I'm guessing that it's because of the use of jQuery(this) but I don't understand what to replace it with. Note that this is not because jQuery isn't declared as a global.


回答1:


I think the problem is that you use this not inside of a method. The following code

/*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");
    }
};

or this one

/*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");
}

will give you no errors or warnings.

UPDATED: One more version, which is very close to your original one, also has not errors or warnings:

/*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");
};

UPDATED 2: I find the question interesting for understanding. So I look through ECMAScript standard . I find the following in the "Annex C (informative) The Strict Mode of ECMAScript" (see better in HTML version here):

If this is evaluated within strict mode code, then the this value is not coerced to an object. A this value of null or undefined is not converted to the global object and primitive values are not converted to wrapper objects. The this value passed via a function call (including calls made using Function.prototype.apply and Function.prototype.call) do not coerce the passed this value to an object (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).

I suppose that it is the reason of the JSLint error.

Of cause if you would switch off the strict mode the code will have no more errors:

/*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");
}

UPDATED 3: It seems that impossibility of the usage of this in the function statement and the possibility of the usage of this in the function expression seems suspected for many people. Today I received one more comment about this. So I created very simple demo

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

    test();
}());

You can test it here that in IE9 the demo display alert with the text "[object Window]" and on the current versions of Chrome and Firefox you will see "undefined".

So the problem with the usage of this in function statement is not "a jslint thing". It's real problem which you should take in considerations during development of your JavaScript programs.

I personally prefer to use function expression and almost never use more function statements. I think that the people who come from another program languages (like me too) try at the beginning to use the same construction which was good in your favorite languages. Only later one finds out that definition of variables in block is bad (there are no block level scope in JavaScript) and that function statements is not always the best choice too.




回答2:


There is no strict mode violation in your code. If there was, you'd get an Error of some sort.




回答3:


By native javascript, this will be undefined in strict mode if the function contains it is not invoked either:

  • as a method of an object
  • by Function.call or Function.apply
  • as a constructor

That's the reason jshint is complaining about it.

However, if the function is being used as a event handler for jQuery, jQuery will force the $(this) as the jQuery object of the DOM that fires the event.

To prove this, open the console of this page and run the following code.

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

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

Click any question or answer of this page and you would see the background becomes red.




回答4:


Much easier! Just use ev.currentTarget instead of this. It is the same as you can test with ===

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


来源:https://stackoverflow.com/questions/7300005/javascript-jslint-what-to-replace-jquerythis-with-when-using-use-strict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!