Reputation: 125
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
Reputation: 17453
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.
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
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
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
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
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