98

I think this may be a duplicate of Strict Violation using this keyword and revealing module pattern

I have this code:

function gotoPage(s){
    if(s<=this.d&&s>0){this.g=s; this.page((s-1)*this.p.size);}
}

function pageChange(event, sorter) {
    var dd = event.currentTarget;
    gotoPage.call(sorter, dd[dd.selectedIndex].value);
}

And JSHINT (JSLINT) is complaining. It says "Strict violation." for the highlighted line:

enter image description here

Is my use of Function.call() and then referencing the instance, somehow inappropriate?

Is this considered to be bad style?

Community
  • 1
  • 1
Cheeso
  • 180,104
  • 92
  • 446
  • 681
  • Does it only say "Strict violation", without any detailed error message? – stivlo Oct 07 '11 at 14:40
  • I can't reproduce the problem, I ran the code through JSHint and JSLint and it's not seeming to complain about anything. – Peter Olson Oct 07 '11 at 14:40
  • 54
    Note that this would be much easier to diagnose if you didn't try to cram it into a ridiculous one-liner :P. – Domenic Oct 07 '11 at 14:43
  • 1
    I've seen this in another question (can't find it right now). It has to do with the use of `this`. I've no idea why JSLint would call it a Strict Violation, but I do know that if you don't define the `this` value of a function, it will be `undefined` in strict mode. Clearly you're defining `this`, so it shouldn't be an issue. – user113716 Oct 07 '11 at 14:47
  • 2
    You can ignore these *possible strict violations* with `"-W040":true` in the config json, but since json doesn't have comments, you can't tell anyone why it's there. – kojiro Apr 05 '13 at 17:17

4 Answers4

124

JSHint says "Possible strict violation" because you are using this inside something that, as far as it can tell, is not a method.

In non-strict mode, calling gotoPage(5) would bind this to the global object (window in the browser). In strict mode, this would be undefined, and you would get in trouble.

Presumably, you mean to call this function with a bound this context, e.g. gotoPage.bind(myObj)(5) or gotoPage.call(myObj, 5). If so, you can ignore JSHint, as you will not generate any errors. But, it is telling you that your code is unclear to anyone reading it, because using this inside of something that is not obviously a method is quite confusing. It would be better to simply pass the object as a parameter:

function gotoPage(sorter, s) {
    if (s <= sorter.d && s > 0) {
        sorter.g = s;

        sorter.page((s - 1) * sorter.p.size);
    }
}

function pageChange(event, sorter) {
    var dd = event.currentTarget;
    gotoPage(sorter, dd[dd.selectedIndex].value);
}
Domenic
  • 100,627
  • 39
  • 205
  • 257
  • 2
    You're probably right that its complaint is that the function is not defined *explicitly* as a method. Seems silly for JSLint/Hint to call it a *"Strict violation"* though. – user113716 Oct 07 '11 at 14:55
  • In the web interface and in the latest version, it calls it "_possible_ strict violation." – Domenic Oct 07 '11 at 15:05
  • 12
    Even so, I think they're being a little misleading in the description. Even if `this` does end up being `undefined`, then the *actual* issue isn't just a *strict mode* violation. They would do better to give a warning saying that `this` may be `undefined` when in "strict mode", leading to a `TypeError` (or something). – user113716 Oct 07 '11 at 15:13
  • 11
    @ripper234 indeed, that's why I always use `event.currentTarget` instead of `this`. – Domenic Dec 10 '12 at 03:50
  • 4
    What config directive can I add to `.jshintrc` to disable this check? – callum Feb 05 '14 at 17:09
  • 3
    Very nice explanation (+1). "_It would be better to simply pass the object as a parameter_" suggestion really improves code quality. – Tom Mar 19 '14 at 12:06
  • 7
    @callum "validthis": true – Brett Apr 30 '14 at 23:25
  • 18
    Use `/* jshint validthis: true */` if you only have a couple and don't want to change for every case. – knownasilya Jul 24 '14 at 14:21
  • If you assign the function to an eventListener callback for example, then you cannot use parameters anyway... – mr1031011 Dec 29 '17 at 01:38
  • @Domenic wow, using even.currentTarget really makes the trick ! great :D – DevMoutarde Mar 13 '18 at 09:37
93

I've had this message for a function that did not start with a capital letter.

"use strict";

// ---> strict violation
function something() {
    this.test = "";
}


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}
amenthes
  • 2,817
  • 30
  • 37
  • 29
    I would note that jshint is probably assuming, due to convention, that `Something` is a constructor due to the capital S, and so should be called using `new`. Doing so defines `this` to be a new object based on `Something.prototype'. It's most likely due to that assumption that it doesn't raise the possible strict violation warning. – Andy Merts Jan 07 '15 at 21:33
  • 4
    I had this error on an AngularJS provider, therefore upper-camel-case method names are expected and I had lower-camel-case. Fixed. – Deminetix Mar 24 '15 at 00:27
  • I had the similar problem, when having a function name only lowercase, renaming using a Capital. – GibboK Jul 09 '15 at 08:48
  • Don't use capital first letter because it also a constructor, you will face another problem. instead of, you can use: var fnAbc = function(){this.test = ""} – Hieu Tran AGI Apr 27 '17 at 02:32
  • The capital letter does not change anything about the inner workings of the function. It is just something programmers usually do this way to convey meaning. In other words: this is not a technological problem, but one of communication between homans. – amenthes Apr 28 '17 at 08:05
9

If you declare the function as a variable instead of using the standard function declaration, jshint will not flag this as a strict violation. So you may do the following -

var gotoPage = function (s){
    if(s<=this.d&&s>0){this.g=s; this.page((s-1)*this.p.size);}
};


var pageChange = function (event, sorter) {
    var dd = event.currentTarget;
    gotoPage.call(sorter, dd[dd.selectedIndex].value);
};
asulaiman
  • 1,061
  • 9
  • 16
0

If you're trying to implement a method, you might want to assign to the prototype instead:

ExampleClassName.protytpe.gotoPage = function gotoPage(s){
  // code using this
};

JSHint won't warn when the function is being assigned.

Flimm
  • 97,949
  • 30
  • 201
  • 217
  • Still not good enough. `ClassName.prototype.myMethod = myMethod;`, then defined the method below. You still get an error even though myMethod is correctly bound. – Jefftopia Nov 01 '16 at 14:56