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.
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.
Share Improve this question asked Sep 6, 2012 at 13:51 SamuelSamuel 12.3k6 gold badges51 silver badges72 bronze badges4 Answers
Reset to default 9You 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/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
- Constructor call (using the
new
keyword) wherethis
is the new object which is returned automatically. - Method call if a function is attached to an object and called from it then
this
is the object called from. - Function call a direct call to a function will result in
this
being the global object, (a mon mistake when calling a contstructor without new) - Apply\Call call when using a method to specify what this should be (see jackwanders as an example)
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
.
- line 1 we then attach a 'name' variable to
this
and initialise with the passed parameter. - line 2 we then attach a 'hello' function to
this
. - line 3 the function expects to have a 'name' variable exist attached to this (which it does for now).
- line 4 rather than return
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;
}
You appear to be confusing two things.
a) Regular functions
function CreatePerson(name) {
// create a new object
var person = {};
// or (if you want to provide a prototype)
var person = Object.create(...);
// fill it with some more data
person.name = name;
person.foo = 123;
person.bar = function() { /* ... your method body ... */ };
}
That's invoked like:
var person = CreatePerson("Jack");
b) Constructors
function Person(name) {
// called after a Person is created,
// `this` is bound to the new object
// and its prototype is set to `Person.prototype`
this.name = name;
this.foo = 123;
this.bar = function() { /* ... your method body ... */ };
}
var person = new Person("Jack");
Note the special new
syntax here.
When using this style, you'll probably want to create the methods only once, not for every created instance:
function Person(name) {
// called after a Person is created,
// `this` is bound to the new object
// and its prototype is set to `Person.prototype`
this.name = name;
this.foo = 123;
}
Person.prototype.bar = function() {
/* ... your method body ... */
};
var person = new Person("Jack");
Doing like this works.
If you only want to access the this within the function you can do like this. you use the return {hello:hello} to declare the function and you don't need do to it, unless it's what you want
example 1
function _persons(array) { this.available = array; this.write = function () { writedata(this.available, '#array2'); }; this.SortAge = function () { array.sort(pare); writedata(this.available, '#array3'); }; array.sort(pareName); } var users = new _persons(myarray);
example 2
function Person(name ){ this.name = name ; this.hello = function(){ alert("hello " + this.name); } } var a = "john"; var newPerson = new Person(a); newPerson.hello(); var otherPerson = new Person("annie"); otherPerson.hello();