I have this code:
function Person(name){
var self = this;
this.name = name;
function hello(){
alert("hello " + self.name);
}
return {
hello: hello
};
}
var newPerson = new Person("john");
newPerson.hello();
I want to be able to use the 'this' keyword to access the 'name' property in the 'hello' function; I want an alternative to using the 'self' variable.
Except using the $.proxy function of jquery to control the context, how can I write the same code but without the variable 'self'?
I want a code that looks like below but 'name' is always 'undefined' when I call 'newPerson.hello()'. I don't know why because I have always believed that the scope of a function is always the object at the left of the dot of the caller and in this case, it's 'newPerson' that have been assign a value 'john' when creating the object.
function Person(name){
this.name = name;
function hello(){
alert("hello " + this.name);
}
return {
hello: hello
};
}
var newPerson = new Person("john");
newPerson.hello();
Thank you.
You can use .bind to force the owner of a function to be whatever object you pass. So, you can write your Person object like so:
function Person(name){
this.name = name;
var hello = function(){
alert("hello " + this.name);
}.bind(this);
return {
hello: hello
};
}
This will ensure that .hello always executes in the context of the Person that is calling it.
Here's a demo:
--- jsFiddle DEMO ---
Don't use return by default when using the new keyword the function will return this
you will need to change how your function is declared how ever.
Here is a fiddle
http://jsfiddle.net/SaintGerbil/9SAhD/
function Person(name){
this.name = name;
this.hello = function (){
alert("hello " + this.name);
}
}
var newPerson = new Person("john");
newPerson.hello();
EDIT if you require name to be private then here is an alternative
function Person(name){
var _name = name;
this.hello = function (){
alert("hello " + _name);
}
}
var newPerson = new Person("john");
newPerson.hello();
In answer to your question there are 4 ways to call a function
These affect the value of this they are
new keyword) where this is the new object which is returned automatically.this is the object called from.this being the global object, (a common mistake when calling a contstructor without new)FURTHER EDIT
So taking your desired code at the start and explaining what is happening.
function Person(name){
this.name = name; // 1
function hello(){ // 2
alert("hello " + this.name); // 3
}
return {
hello: hello
}; //4
}
Person as a function can be called two ways:
var x = Person("ted");
and
var x = new Person("jimmy");
Since you have named Person with a capital it implies that you are expecting people to use new.
So sticking with that we enter the function and javascript creates a new object and assigns it to this.
this and initialise with the passed parameter. this.this (default behavior) we are now declaring a new object and attaching the function to it. This new object does not have a 'name' variable with in its scope.So when you create the object you get an object with a function attached but it cannot get to the variable it needs to execute correctly. Which is why you are getting the undefined.
Does that make sense I always worry that I'm waffling when I have to expand the textbox?
Or if I wrote out your function as verbosely as possible it would look something like this.
function Person(name){
var this = new Object();
this.name = name;
var hello = function (){
alert("hello " + this.name);
}
this.hello = hello;
var that = new Object();
that.hello = hello;
return that;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With