musicman Posted April 21, 2016 Share Posted April 21, 2016 (edited) Hi, I'm studying a constructor function pattern. I have made this constructor: function Person( firstname, age, place ) { this.firstname = firstname; this.age = age; this.greeting = { Hello: function(){ console.log( "Hello " + firstname ); }, YouAre: function(){ console.log( "You are " + age + " years old"); } } this.greeting2 = { Hello: function(){ console.log( "Hello " + this.firstname ); }, YouAre: function(){ console.log( "You are " + this.age ); } } } Person.prototype = { greeting3: { Hello: function(){ console.log( "Hello " + this.firstname ); }, YouAre: function(){ console.log( "You are " + this.age ); } } } var Clara = new Person( 'Clara', '20' ); Clara.greeting.Hello(); // Hello Clara Clara.greeting.YouAre(); // You are 20 years old Clara.greeting2.Hello(); // Hello undefined Clara.greeting2.YouAre(); // You are undefined Clara.greeting3.Hello(); // Hello undefined Clara.greeting3.YouAre(); // You are undefined On the greeting2.Hello and greeting2.YouAre methods, 'this' name and age result is undefined, the same with greeting3 method. The question is: How do we get a property value through a method inside an object array? and who is 'this' in greeting2 and greeting3 functions? Thanks! Edited April 21, 2016 by musicman Link to comment Share on other sites More sharing options...
Ingolme Posted April 21, 2016 Share Posted April 21, 2016 this most likely refers to greeting2/greeting3 rather than Person. You should have a reference to the object itself like this: function Person( firstname, age, place ) { var self = this; self.firstname = firstname; self.age = age; self.greeting = { Hello: function(){ console.log( "Hello " + firstname ); }, YouAre: function(){ console.log( "You are " + age + " years old"); } } self.greeting2 = { Hello: function(){ console.log( "Hello " + self.firstname ); }, YouAre: function(){ console.log( "You are " + self.age ); } } } For greeting3, if you want access to the self variable it will need to be declared inside the Person function. 1 Link to comment Share on other sites More sharing options...
musicman Posted April 21, 2016 Author Share Posted April 21, 2016 (edited) Thank you, Ingolme! All works well now. Just an additional remark, have to make global var with the 'self' object, so we can use it in greeting3 as well. var elem; function Person( firstname, age, place ) { elem = this; this.firstname = firstname; this.age = age; this.greeting = { Hello: function(){ console.log( "Hello " + firstname ); }, YouAre: function(){ console.log( "You are " + age + " years old"); } } this.greeting2 = { Hello: function(){ console.log( "Hello " + elem.firstname ); }, YouAre: function(){ console.log( "You are " + elem.age + " years old" ); } } } Person.prototype = { greeting3: { Hello: function(){ console.log( "Hello " + elem.firstname ); }, YouAre: function(){ console.log( "You are " + elem.age + " years old" ); } } } var Clara = new Person( 'Clara', '20' ); Clara.greeting.Hello(); // Hello Clara Clara.greeting.YouAre(); // You are 20 years old Clara.greeting2.Hello(); // Hello Clara Clara.greeting2.YouAre(); // You are 20 years old Clara.greeting3.Hello(); // Hello Clara Clara.greeting3.YouAre(); // You are 20 years old Thanks again! Edited April 21, 2016 by musicman Link to comment Share on other sites More sharing options...
Ingolme Posted April 21, 2016 Share Posted April 21, 2016 Making it global has the problem that if you create more than one instance of the object "self" only refers to the last instance created. Just try creating two people and you'll see the problem. Why is it necessary to have greeting 3 outside of the constructor? Link to comment Share on other sites More sharing options...
musicman Posted April 21, 2016 Author Share Posted April 21, 2016 (edited) oh you're right. So the best way to do this is to keep the methods inside its constructor.. are you agree? function Person( firstname, age, place ) { var elem = this; this.firstname = firstname; this.age = age; this.greeting = { Hello: function(){ console.log( "Hello " + firstname ); }, YouAre: function(){ console.log( "You are " + age + " years old"); } } this.greeting2 = { Hello: function(){ console.log( "Hello " + elem.firstname ); }, YouAre: function(){ console.log( "You are " + elem.age + " years old" ); } } } var Clara = new Person( 'Clara', '20' ); var Jason = new Person( 'Jason', '25' ); Clara.greeting.Hello(); // Hello Clara Clara.greeting.YouAre(); // You are 20 years old Clara.greeting.Hello(); // Hello Clara Clara.greeting.YouAre(); // You are 20 years old Jason.greeting2.Hello(); // Hello Jason Jason.greeting2.YouAre(); // You are 25 years old Jason.greeting2.Hello(); // Hello Jason Jason.greeting2.YouAre(); // You are 25 years old Clara.greeting2.Hello(); // Hello Clara Clara.greeting2.YouAre(); // You are 20 years old Edited April 21, 2016 by musicman Link to comment Share on other sites More sharing options...
justsomeguy Posted April 21, 2016 Share Posted April 21, 2016 If you're defining those yourself then yeah, that's the best way. You typically only need to modify the prototype if you're trying to extend something that is built-in or that you imported from somewhere else. Although this is the usual way to do that, rather than assigning an entire object to the prototype: Person.prototype.greeting3 = { Hello: function(){ console.log( "Hello " + this.firstname ); }, YouAre: function(){ console.log( "You are " + this.age ); } }Also, you can always use console.log to print this to see what it's set to. The default is the window object unless it's in another scope. Link to comment Share on other sites More sharing options...
musicman Posted April 22, 2016 Author Share Posted April 22, 2016 Thanks @justsomeguy! this return [object Object] in greeting3. I think this represents the key-value (?). And one thing I have learned from this study is how to add methods into a constructor as object array. It seems like we shouldn't use methods in object array to modify a constructor prototype. Link to comment Share on other sites More sharing options...
Ingolme Posted April 22, 2016 Share Posted April 22, 2016 this most likely refers to greeting3. If it was referring to the parent object it would be [object Person] 1 Link to comment Share on other sites More sharing options...
musicman Posted April 23, 2016 Author Share Posted April 23, 2016 When I check this constructor, this came from the function: Person.prototype.greeting3 = { Hello: function(){ console.log( this.constructor ); }, YouAre: function(){ console.log( this.constructor ); }}// function Object() { [native code] }// function Object() { [native code] } Link to comment Share on other sites More sharing options...
musicman Posted April 23, 2016 Author Share Posted April 23, 2016 If I may ask another basic question, I read this article and I couldn't get Step #4. I just couldn't get when it say: When our _() function returns this , it is actually returning the entire window, or the global scope. Therefore, when we call _().toggle() , we are asking the browser to call the toggle() method which belongs to the window. Obviously this fails.This problem can be solved by recursively creating another _ object using the new keyword. why would we use this condition in a constructor like shown in the article (Step #4)..? if (window === this) { return new _(id); } Thanks! Link to comment Share on other sites More sharing options...
justsomeguy Posted May 4, 2016 Share Posted May 4, 2016 If you try to print this it will always print that it is an object. That's what it shows when you tell it to print an object, and this is always an object unless you specifically set it to something strange. why would we use this condition in a constructor like shown in the article (Step #4)..?By default, this is usually set to the window object. That condition checks if that is the case and, if so, returns a new "_" object. The reason that works is because of the new keyword. It creates a new object and returns that if you are running in the global scope. Otherwise, it just returns the current scope. 1 Link to comment Share on other sites More sharing options...
musicman Posted May 6, 2016 Author Share Posted May 6, 2016 Thanks! I got it now. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now