-2

I have the following code

$(document).ready(function($) {
   "use strict";
   generalClass = function() {

   this.ip               = false; // page page
   this.ie               = false; // IE
   this.pp               = false; // portfolio page
   this.om               = false; // organize menu
   this.wc               = false; // shop
   this.sh               = false; // side header

   // So we can get the correct $this if needed
   $this               = this;

   this.__init();

} 

generalClass.prototype = {

   __init: function( $check ) {

    // Run functions
    $this.__format();
    $this.__resize(); 
   }
}
});

But I am getting that $this is undefined. I have tried writing it as var $this but still it is undefined for $this.__format();. I realise that I can use this instead of $this, but there are instances later in the code where I can't. How do I make it so that $this is defined in the __init() function? So that it refers to generalClass.

Thanks!

bipen
  • 36,319
  • 9
  • 49
  • 62
Johnny
  • 9,725
  • 5
  • 29
  • 34
  • What are you trying to do in the first place? – Hackerman Aug 26 '16 at 17:50
  • Possible duplicate of [javascript - accessing private member variables from prototype-defined functions](http://stackoverflow.com/questions/436120/javascript-accessing-private-member-variables-from-prototype-defined-functions) – JJJ Aug 26 '16 at 17:51
  • Check this answer related to **"use strict"** mode: [What does “use strict” do in JavaScript, and what is the reasoning behind it?](http://stackoverflow.com/a/11496488/2247494) – jherax Aug 26 '16 at 17:53
  • Possible duplicate of [What does "use strict" do in JavaScript, and what is the reasoning behind it?](http://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it) – jherax Aug 26 '16 at 17:54
  • @jherax This doesn't have anything to do with strict mode. – JJJ Aug 26 '16 at 17:54
  • I assumed it had something to do with use strict as the code was working perfectly fine before i added use strict. – Johnny Aug 26 '16 at 17:56
  • @Juhana Of course yes! "use strict" avoid the access to global object, also when creating constructors, a exceptions is raised when no used the `new` operator to created the instance. Also you cant create global variables without `var` keyword. – jherax Aug 26 '16 at 17:57
  • 1
    It *looked like* it was working "perfectly fine", but you actually had only one global variable that was shared by all instances, and possible other classes that also used the same global variable. – JJJ Aug 26 '16 at 17:58
  • @jherax The problem is still the same whether you're in strict mode or not. Strict mode only throws an error instead of letting the dev shoot themselves in the foot. – JJJ Aug 26 '16 at 17:59
  • **"use strict"** does not allow you to use the `$this` if it was not declared in the outer/global scope with the keyword `var`. Also if you call `generalClass` without the `new` operator, the `this` inside the function will not work. – jherax Aug 26 '16 at 18:01
  • But I'm doing all that stuff. Shouldn't var $this be available to the __init function? – Johnny Aug 26 '16 at 18:13
  • Show the code with which you call `generalClass` and the code where you declare `$this`, preferably all in one code block with what you already provided. – trincot Aug 26 '16 at 18:34
  • @JohnnySimpson No. Read the duplicate I linked earlier. – JJJ Aug 26 '16 at 18:36

1 Answers1

3

First of all, if you want to use strict-mode, then you have to put var (or let, or const) before your generalClass and $this.

Like that:

(function () {
    "use strict";
    var generalClass = function() {

        this.ip               = false; // page page
        this.ie               = false; // IE
        this.pp               = false; // portfolio page
        this.om               = false; // organize menu
        this.wc               = false; // shop
        this.sh               = false; // side header

        // So we can get the correct $this if needed
        var $this             = this;

        this.__init();
    };

    generalClass.prototype = {

        __init: function( $check ) {
            console.log('$this', $this);
            // Run functions
            $this.__format();
            $this.__resize();
        }
    }

    var instance = new generalClass();
}());

(I changed $(document).ready() to IIFE so I could run it in console. Plus, I created instance of your class.)

What happens now? $this inside __init() is not defined. You would have to define $this inside __init() but here is the problem: what should be assigned to it?

In your example of __init() you could actually call this instead of $this but as you already pointed it’s not always possible.

But let me illustrate it with more abstract example:

(function () {
    var GeneralClass = function () {
        this.foo = [1, 2, 3];
        this.bar = 4;
        this.baz = [5];
    };

    GeneralClass.prototype.someFunction = function () {
        console.log('foo', this.foo); // [1, 2, 3]
        console.log('bar', this.bar);

        var self = this; // storing reference to *this* (oobject for later)

        this.baz.forEach(function (item) {
            console.log('baz?', this.baz); // undefined, because *this* means here this.baz, and there is no this.baz.baz
            console.log('baz!', self.baz); // [5]
        });

        console.log('foo * bar');
        this.foo.forEach(function (item, index) {
            console.log('item', index, 'value', item * self.bar);
        });

        console.log('Both accesible here', this.bar, self.bar);
    };

    var generalClassInstance = new GeneralClass();
    generalClassInstance.someFunction();
}());

Here I assign this to self (personally, I’d use $this for $(this) but it’s only a convention so do as you please, as long as you are consistent). Now functions called inside my function can use self which works as a reference to outer this. And if I called another function in my sub-function, it would still point to GeneralClass’s this.

I hope this is what you were primarily interested in.

The Witness
  • 910
  • 7
  • 12