JSLint Error: Unexpected 'this'

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

Having trouble understanding why JSLint is surprised by my use of this in the following code:

function testConstr (x) {     'use strict';     this.joker = "Whyyy sooo seriousss?";     this.x = x; }

For both property assignments, JSLint says: Unexpected 'this'. How do I correct my code?

回答1:

Your code might be perfectly correct (it might also be problematic, depending on how you call testConstr).

My suggestion is: tell JSLint to shut up

Or don't use JSLint at all.



回答2:

So in other words, JSLint doesn't automatically expect me to use a constructor pattern?

You know, I think you're right. Your question bugged me, and I signed up for Crockford's JSLint discussion group and asked. He replied, but ignored the solution I'm going to present, below, which I think means that it's okay, the same way JSLint doesn't complain if something passes muster.

(I'm still waiting for an updated Good Parts, though.)

That caveat aside, here's what I'd suggest doing for OO JavaScript that passes Beta JSLint (as of today, anyhow).

I'm going to rewrite an example from MDN's page, "Introduction to Object Oriented Programming," which itself uses this liberally.

With this

Here's the original, unlinted MDN example from the section linked, above:

var Person = function (firstName) {   this.firstName = firstName; };  Person.prototype.sayHello = function() {   console.log("Hello, I'm " + this.firstName); };  var person1 = new Person("Alice"); var person2 = new Person("Bob");  // call the Person sayHello method. person1.sayHello(); // logs "Hello, I'm Alice" person2.sayHello(); // logs "Hello, I'm Bob" 

That follows the conventions we know and love.

Without this

It's pretty easy to figure out how to make "constructors" that don't follow that pattern, but we lose use of prototype, if I'm not missing something, and have to include all of the object's methods in our constructor that we want all of our Peeps to share.

/*jslint white:true, devel:true */ var Peep = function(firstName) {     "use strict";     var peep = {};     peep.firstName = firstName;      peep.innerSayHello = function() {         console.log("Hello, I'm " + peep.firstName + ".");     };      return peep; };  var peep1 = new Peep("Bob"); var peep2 = new Peep("Doug");  peep1.innerSayHello(); peep2.innerSayHello(); 

So there's a lintable alternative. That does, other than the return peep; and the inner definition of methods, make JavaScript act like many OO-first languages you might encounter. It's not wrong, at least.

Not having access to prototype isn't horrible; it's really bad news to change prototype somewhere that's not right beside the constructor, as your code would go to spaghetti. "Some Persons have sayGoodbye() and some don't, depending on if we'd amended the prototype at the point of their construction." That's awful. So this alternative convention has its advantages.

You can still, of course, add functions to a single instantiation of Peep later, but I'm not sure how you'd access firstName without using this, so perhaps he wants us to stop munging objects after construction.

person1.sayGoodbye = function (other) {      console.log("Goodbye, " + other + ".");  }; 

(I mean, we could also still monkey-patch Peep to change it mid-process, but that's horrible, stupid programming. Usually.)

Inheritance (without this)

And inheritance is easy enough, I think.

var PeepWithGoodbye = function (firstName) {     "use strict";     var peepWithGoodbye = new Peep(firstName);      peepWithGoodbye.innerSayGoodbye = function (otherPeep) {         if (undefined === otherPeep) {             otherPeep = { firstName: "you" };         }         console.log("This is " + firstName              + " saying goodbye to " + otherPeep.firstName + ".");     };      return peepWithGoodbye; };  var pwg1 = new PeepWithGoodbye("Fred"); pwg1.innerSayHello();           // Hello, I'm Fred. pwg1.innerSayGoodbye(peep1);    // This is Fred saying goodbye to Bob. pwg1.innerSayGoodbye();         // This is Fred saying goodbye to you. 

EDIT: See also this answer where the asker later found Crockford's suggested means of creating OO javascript. I'm trying to convince that guy to delete that Q&A and move the A here. If he doesn't, I'll probably add his stuff and community wiki it here.


EDIT: See this from MDN for why it works:

(Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)



回答3:

'use strict';  var SudoConstructor = (function () {      /* We need bind, 


回答4:

In a strict mode this reference is set to undefined.

So both your statements will cause reading properties of the undefined object, which will lead to an exception.

How do I correct my code?

Remove both those lines.

UPD: what I state above is how JSLint treats your code, not how I do that.



回答5:

JSLint says: Unexpected 'this'. How do I correct my code?

There is no need to correct your code.

In the help page for JSLint, in the section for the /*jslint*/ directive, a "Tolerate this" option has been added to the table of available options:

+---------------+------+---------------------------------+ | Tolerate this | this | true if this should be allowed. | +---------------+------+---------------------------------+ 

So, to suppress complaints about the use of this, place the following directive into your source file before the first statement:

/*jslint     this */ 

(Note that other /*jslint*/ options may follow this by inserting a comma between options. See the JSLint help page.)

Also see the answer by @Oriol to enable the "Tolerate this" option in the user interface for JSLint.



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