5

Consider this simple example:

"use strict";
var Foo = {
    field: 0,
    func: function () {
        this.field = 4;
    }
}

JSLint throws the error:

Unexpected 'this'. At the line "this.field = 4".

I've seem some questions here in StackOverflow asking for this, and in all the cases, the answer was just to enable the "Tolerate this" flag. However, I'm interested in why do the JSLint creators think the use of "this" is (or might lead to) an error.

Also, how would I implement member functions without the "this" keyword and without expecting the user to pass the instance as the first argument?

EDIT Maybe I didn't make myself clear enough in that this question, despite looking similar doesn't have an answer to what I'm asking: JSLint Error: Unexpected 'this'

The problem with that question is not the question itself but rather the answers it got. Note how the accepted answer is: "My suggestion is: tell JSLint to shut up". And I specifically say in my post that this is not a valid answer to me, as I want to understand why is the use of this forbidden by JSLint, not how to avoid that error.

Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
Setzer22
  • 1,589
  • 2
  • 13
  • 29
  • Just a note, JSLint does not only forbid things which can lead to errors. It "forces" you to use a specific coding style. – meskobalazs Aug 08 '15 at 10:28
  • 2
    I would like to note I especifically mention in my question that it's different from the one I'm "duplicating", despite not specifically citing the link. Specifically when I said: "I've seem some questions here in StackOverflow asking for this, and in all the cases, the answer was just to enable the "Tolerate this" flag." I was referring to that very question, among others. Note that the accepted answer in that question is not acceptable from my point of view, as disabling the error doesn't explain what caused it and why was it caused. – Setzer22 Aug 08 '15 at 10:35
  • @meskobalazs, Good to know. Still, I'm intrigued what's the "good" coding style that avoids "this" and why is this apparently proper use of the "this" keyword flawed according to JSLint. – Setzer22 Aug 08 '15 at 10:37
  • You should ask Douglas Crockford that :) Maybe he wrote it down in *The Good Parts*. – meskobalazs Aug 08 '15 at 10:41
  • You're right, maybe I should. Better go to the source if I want to know the real "why". – Setzer22 Aug 08 '15 at 10:44
  • 2
    I think the accepted answer from the duplicated question is not helpful at all, but there is another, much more detailed answer there that talks about different types of inheritance. Also, the [the JSLint help](http://jslint.com/help.html) says: "Having this in the language makes it harder to talk about the language. It is like pair programming with Abbott and Costello. Avoid using this." (But this still doesn't really explain _why_... :-)) – pdenes Aug 08 '15 at 10:54
  • @pdenes Yes, one of the answers is way more useful, but still doesn't answer why should a feature such as "this" to be forbidden from the language. As I mentioned, it looks like the only way to properly and easily implement member functions to me, which are a key concept in OO programming. – Setzer22 Aug 08 '15 at 11:01
  • @Setzer22: fair enough, reopened. – georg Aug 08 '15 at 11:23
  • Doug forces functional style on you :P He stopped using this. – Blago Eres Aug 08 '15 at 11:54
  • @BlagoEreš And that's exactly why I'm asking. I think the author of JSLint does wrong in not telling the user the motive for some of its errors. One might just assume Doug thinks Object Oriented programming is bad, and is telling people they should program in another style, namely FP. But in the end, this might not be the real reason. At this point I'm using this in my code and just enabling the "allow this flag" on JSLint (or not using it at all), but I really want to know why is that error message there. – Setzer22 Aug 08 '15 at 12:36
  • @Setzer22 Here you go :) http://www.jslint.com/help.html#this I agree with him about lot of stuff but not about banning `this` – Blago Eres Aug 08 '15 at 12:55
  • @BlagoEreš Sadly, apart from a joke, little can be learnt for the particular explanation on this. Thanks for the resource though. – Setzer22 Aug 08 '15 at 13:21
  • I found this discussion about erm... `this`: https://plus.google.com/communities/104441363299760713736/s/Berriman%20new%20version%20fails -- there aren't many details, but there are at least some answers from Douglas Crockford. – pdenes Aug 08 '15 at 14:27
  • @pdenes Thank you. I've read the thread and watched the related youtube talk by Douglas. And I think I've got some idea of why the "this" keyword is discouraged by JSLint. I've also tried to e-mail Doublas with my specific question and will post the answer if there's any luck with that. If no one answers the question I'll try to make some answer with what I've been able to find out tomorrow. – Setzer22 Aug 08 '15 at 20:20
  • @georg A little late to the party, but this is still a dupe. There are, eg, [answers other](http://stackoverflow.com/a/30375300/1028230) than "tell JSLint to shut up", and that question would benefit from Setzer's own answer & research, below, even if the OP seems to continue to select the "wrong" answer. ;^) – ruffin Oct 16 '15 at 16:28

1 Answers1

2

As @pdenes pointed out in the comments, there has been some discussion on the topic here: https://plus.google.com/communities/104441363299760713736/s/Berriman%20new%20version%20fails

There's also a Douglas Crockford youtube talk called "The Better Parts" in which Douglas exposes some of his opinions on this, and proposes a (in his opinion) better way to make a constructor.

The proposed constructor pattern looks like this (directly taken from his talk, it also illustrates some features of ES6):

function constructor(specs) {
    let {member} = spec, 
        {other} = other_constructor(spec),
        method = function() {

        };
    return Object.freeze({
        method,
        other
    });
}

The "pattern", as I understand it, is to avoid using "this" and any other way of object creation (by means of new, or Object.create), getting also rid of prototypal inheritance.

At this point, the constructor is now a function that returns an object (in this case, frozen, but there's no need for that actually).

All the "object-oriented" stuff is achieved by storing the members and methods in the constructor's closure, and member function can refer to those by name because they're present in the current scope. That successfully avoids the use of "this".

Sadly, the real answer I get from this is that there are many convoluted ways to create an object in javascript, and IMO each one has its flaws. JSLint is a nice tool, but no one should be following it without doing some research and understanding why are those errors given. Especially when no real, comprehensive reason is offered. Not even by the author.

ruffin
  • 16,507
  • 9
  • 88
  • 138
Setzer22
  • 1,589
  • 2
  • 13
  • 29
  • That's a good answer. It's certainly fair to accept your own answer here so we can cross it off of the JSLint unanswered pool. Actually, better is to delete this dupe & post your answer at the other question. I hadn't seen that video when [I answered there](http://stackoverflow.com/a/30375300/1028230). Your answer would be helpful. I do understand the delta between "avoid" and "understand" you're making, but it's useful to help everyone understand who might otherwise mindlessly avoid. (Personally, I don't understand how any JSLint answer can be "don't use JSLint", & that happens too often.) – ruffin Oct 16 '15 at 16:33