Otined
Otined

Reputation: 125

JSLint out of scope when using a var inside the same var

Update: the user.forceLogout() is inside another http request funtion.

I get the following message when using JSLint:

'user' is out of scope. user.forceLogout(); // line...

My code is like:

var user = {
    logout: function () {
        var req = ... 
        $http(req).then(function (response) {
            user.forceLogout();
        });
    },
    forceLogout () {
       // code to force logout
    }
}

What should be the correct way to implement such code?

Upvotes: 1

Views: 151

Answers (5)

ruffin
ruffin

Reputation: 17453

Lints

Sam's pretty close. Here's a twist on the current constructor pattern favored (or at least accepted) by the current version of JSLint.

/*jslint node, white */
var $http = require('https');

var user = (function() {
    "use strict";
    var userToReturn = {};

    userToReturn.forceLogout = function () {
        $http.someAction();      // kludge to keep from "empty block"
    };

    userToReturn.logout = function () {
        var req = {};            // just to push some code in to lint.
        $http(req).then(function (ignore) {
            userToReturn.forceLogout();
        });
    };

    return userToReturn;        // nicely protected object in closure.
}()); // immediate invocation gives you that `userToReturn` within closure.

user.logout(); // inserting to dodge "Unused 'user'." error

You could also create a factory pattern with a non-anonymous function if you wanted to create many of these.

Better

Now I think this workaround is a missed case by JSLint, as you've still called a function attached to an object while you're defining the object, and I bet what JSLint really prefers you do is this:

/*jslint node, white */
var $http = require('https');

var user = (function() {
    "use strict";
    var userToReturn = {};

    // private function for shared logic.
    function _forceLogout() {
        $http.someAction();     // kludge to keep from "empty block"
    }

    userToReturn.forceLogout = _forceLogout;

    userToReturn.logout = function () {
        var req = {};           // just to push some code in to lint.
        $http(req).then(function (ignore) {
            _forceLogout();
        });
    };

    return userToReturn;
}());

user.logout(); // inserting to dodge "Unused 'user'." error

Create a closure, factor out repeated code, then call it as a private method within that closure.


NOTE: Older versions of JSLint might complain about the param called ignore. You can just (/*response*/) if you don't want to take it all the way out. If your code really uses response later in that function, just leave it in, natch!

Apologies if you're not setting $http to require('http'). Change to whatever's appropriate, natch.

Anyhow, both lint as is.

Upvotes: 0

Sam Bauwens
Sam Bauwens

Reputation: 1367

Use a constructor function:

var user = function() {
    var self = this;

    self.logout = function () {
        self.forceLogout();
    };

    self.forceLogout = function () {
       // code to force logout
    };
}

Using the this keyword inside a function will work most of the time but can do weird things sometimes, that's why I assign it to self in the beginning of the constructor function user.

Then you create your user like this :

var myUser = new user();

The new keyword will create a new object and bind it to the this binding of your user constructor function, then it will return that new constructed object into myUser.

Upvotes: 0

matanso
matanso

Reputation: 1292

Your code uses user before is is defined (in the definition). You can define it like this, instead:

var user = {};
user.forceLogout = function(){};
user.logout = function(){ forceLogout(); };

Upvotes: 0

Damian Senn
Damian Senn

Reputation: 1165

It would be better to reference your user using this like:

var user = {
    logout: function () {
        this.forceLogout();
    },
    forceLogout () {
       // code to force logout
    }
}

You might want to read up on this on MDN: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this

Upvotes: 1

Taran J
Taran J

Reputation: 805

use 'this' instead of variable name inside the declaration/definition:

var user = {
    logout: function () {
        this.forceLogout();
    },
    forceLogout () {
        // code to force logout
    }
}

Upvotes: 1

Related Questions