First of all, I'm new to object-oriented JS but fairly experienced with JS and jQuery.
I'm having an issue which makes no sense and is better explained in code, see below:
var $table = $("tbody#peopleContainer"); // hypothetical table to which we will append rows for each person object
var Person = function( name ) { //nothing special here
this.name = name;
this.nickname = "";
}
Person.prototype = {
create: function() {
$tr = $table.append("<tr></tr>"); //create a blank row
this.$name = $('<td>'+this.name+'</td>').appendTo( $tr );
this.$nickname = $('<td><input type="text"></td>').appendTo( $tr );
$table.append( this.$td ).append( this.$nickname );
self = this;
this.$name.on("click", $.proxy(self.logName, self)); // logs the name of the person's row you clicked
$("input", this.$nickname).change(function() { // Should log the nickname you typed as well as the person's name whose nickname you changed
self.nickname = $(this).val();
$.proxy(self.logNameAndNickname, self)(); // Problem! Logs the nickname you typed in, but ALWAYS logs the last instantiated person's name
})
},
logName: function() {
console.log(this.name);
},
logNameAndNickname: function() {
console.log(this.name, this.nickname); // for some reason this.name returns the last instantiated person's name (Person #0).
}
}
// create 100 people and append to table
x = 100;
while ( x-- > 0 ) {
person = new Person("Person #"+x);
person.create();
}
for some reason, logName() logs the right person's name, but logNameAndNickname() always logs the last instantiated person's name, although it logs the correct nickname. It's as if this is referencing 2 separate objects in the same scope.
So my question is - What's going on here?
Followup question: Is this the right way of using jQuery events with objects? I'm new to object oriented JS so please let me know if there's a more appropriate way to accomplish this same thing.