Reputation: 12039
Alright I have a question and I don't know the answer. I am creating an object and the properties of the object are constructor functions. Now within these constructor functions I am referencing this. Would the variable this be referring to the parent object, so if I am creating this.submit in each of the constructors would it be overwriting the previous definition?
The reason I am doing this is because I am looping through each property in my object and if it is a function then I am extending its prototype with Node's Event Emitter so I can dispatch events after successful ajax calls.
Here's an example:
var AccountMethods = function(apiVersion){
return {
/** Used to login users
*
* @param username - {string} Username
* @param password - {string} Password
* @function
*
* @example
* var Login = new Easy.Login('fakeusername', 'fakepassword')
* Login
* .on('done', function(data){
* if(data.success){
* // user is logged in
* } else{
* throw new Error(data.error);
* }
* })
* .on('error', function(err){
* // do something with err
* });
*/
Login: function (username, password) {
this.submit = function () {
$.post(apiVersion + 'account/login', {
username: username,
password: password
})
.done(function (data) {
if(data.success){
this.emit('done', data);
} else{
this.emit('error', data)
}
}.bind(this))
.fail(function (err) {
this.emit('error', {
error: err.status + ' ' + err.statusText + ' : ' + err.responseText
});
}.bind(this));
}
},
/** Used to logout users
*
* @function
*
* @example
* var Logout = new Easy.Logout();
*
* Logout.on('done', function(){
* // user is logged out
* });
*
* Logout.submit();
*/
Logout: function () {
this.submit = function () {
$.post(apiVersion + 'account/logout')
.done(function (data) {
this.emit('done');
}.bind(this))
.fail(function (err) {
this.emit('error', err);
}.bind(this));
}
},
}
}
You can see within the comments example usage. This definitely works the way I want it to, however is it right?
I can do this and it works as expected:
var Login = new Easy.Login('fakeusername', 'fakepassword');
Login.submit();
var Logout = new Easy.Logout();
Logout.submit();
Both submit functions are set within the same parent object using this.submit = ... but it works as expected. Can someone explain this to me?
Upvotes: 3
Views: 153
Reputation: 4506
When you're calling a constructor function with new
, a new, empty object is bound to it as this
, so inside the function this
will refer to the new object that is being created (ie. what will be returned from the new Link()
call.) That means in your example the variables Login
and Logout
are different objects, with different submit methods.
If somebody tried calling Login
without new
, then the value of this
would depend on the calling context: if called as Easy.Login
, then this
would refer to Easy
, but if called as a function reference directly, then the value of this
will depend on whether you have strict mode enabled or not. (See Matt Browne's comment below)
All in all: as long as you're using them only as constructor functions, this approach is correct. But as you see, not calling constructor functions as they were designed to be called can be problematic, hence the convention that constructor functions' names start with capital letters (which you are following correctly), so people don't make the mistake of calling them without new
(most static code analyzers will warn you by default for not following this convention).
Upvotes: 2