Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 304
Sarge Avatar asked Sep 04 '11 14:09

Sarge


People also ask

What is replacing jQuery?

JavaScript: Native JavaScript is one of the most common alternatives to jQuery.

Which command will run script js with strict mode?

Strict mode for scripts To invoke strict mode for an entire script, put the exact statement "use strict"; (or 'use strict'; ) before any other statements.

Should I use strict mode JavaScript?

First, all of your code absolutely should be run in strict mode. Core modern javascript functionality is changed (see . call() and apply()) or disfigured (silent Errors) by executing code outside of strict mode.

Where should we place use strict in JavaScript?

The purpose of "use strict" is to indicate that the code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables. The numbers in the table specify the first browser version that fully supports the directive. You can use strict mode in all your programs.


3 Answers

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.

like image 145
Oleg Avatar answered Oct 18 '22 10:10

Oleg


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

like image 37
user113716 Avatar answered Oct 18 '22 11:10

user113716


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.

like image 26
Malcolm Kee Avatar answered Oct 18 '22 11:10

Malcolm Kee