Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object Oriented questions in Javascript

Tags:

javascript

oop

I've been using javascript for a while, but have never learned the language past the basics. I am reading John Resig's "Pro Javascript Techniques" - I'm coming up with some questions, but I'm not finding the answers to them in the book or on google, etc.

John gives this example in his book:
Function #1

function User( name, age ){   this.name = name;   this.age = age; } // Add a new function to the object prototype User.prototype.getName = function(){   return this.name; }; User.prototype.getAge = function(){   return this.age; }; var user = new User( "Bob", 44 ); console.log("User: " + user.getName() + ", Age: " + user.getAge()); 

I'm still learning about the prototype property, so I tried writing something similar:
Function #2

function User (name, age ) {   this.name = name;   this.age = age;   this.getName = function() {     return this.name;   };   this.getAge = function() {     return this.age;   }; } var user = new User( "Bob", 44 ); console.log("User: " + user.getName() + ", Age: " + user.getAge()); 

It doesn't use the prototype property to create the getName and getAge functions, but the output is the same as John's example.

I took it one step further, and created this:
Function #3

var User = {   name: "",   age: 0,   setName: function(name) {     this.name = name;   },   setAge: function(age) {     this.age = age;   },   getName: function() {     return this.name;   },   getAge: function() {     return this.age;   } }; User.setName("Bob"); User.setAge(44); console.log("User: " + User.getName() + ", Age: " + User.getAge()); 

Again - it looks different than John's example (and I had to add setter methods), but the output is the same.

Question #1 - what is the difference between the 3 functions? What is the advantage of the prototype property, and is Function #2 doing anything incorrectly, because it seems more straight forward to code #2 instead of #1 (although I'm sure #1 is doing it better seeing as John created it).

Question #2 - How could I modify function #3 to not use the setName and setAge methods, but still keep the {...} shorthand? Can the {...} shorthand have constructors?

Thanks in advance for helping me learn!

EDIT I think my 2nd question was a little confusing. I meant how could I use the {...} shorthand to create a User object, but then after I create the object, say something like:

var user = new User("Bob", 44); 

Just like in Function #1 - or is that not possible?

EDIT #2 Wow! Thanks everyone for the awesome answers. That really makes it a lot more clear to me. So if I understand correctly, the difference between #1 and #2 aren't too much. If I only ever create one "User" object - they probably aren't different at all. But if my program creates many User objects, #1 would most likely be more efficient and use less memory since all objects will share the same functions.

I really appreciate all of the great answers - Thanks!

like image 637
BrianH Avatar asked Jan 14 '09 18:01

BrianH


People also ask

What is object in JavaScript interview questions?

What are JavaScript objects? JavaScript objects are data structures that contain both properties and methods. A property is a value that is associated with an object, while a method is a function that is associated with an object. Objects can be created using the Object() constructor or the object literal syntax.

What are the object-oriented concepts in JavaScript?

The Four Principles of OOP. OOP is normally explained with 4 key principles that dictate how OOP programs work. These are inheritance, encapsulation, abstraction and polymorphism. Let's review each of them.

Can I use JavaScript for OOP?

That said, constructors and prototypes can be used to implement class-based OOP patterns in JavaScript. But using them directly to implement features like inheritance is tricky, so JavaScript provides extra features, layered on top of the prototype model, that map more directly to the concepts of class-based OOP.


2 Answers

Every time a function() {} is evaluated, it creates a new function object. Therefore, in #1 all of the User objects are sharing the same getName and getAge functions, but in #2 and #3, each object has its own copy of getName and getAge. All of the different getName functions all behave exactly the same, so you can't see any difference in the output.

The {...} shorthand is a constructor. When evaluated, it constructs a new "Object" with the given properties. When you run "new User(...)", it constructs a new "User". You happen to have created an Object with the same behavior as a User, but they are of different types.

Response to comment:

You can't, directly. You could make a function that creates a new object as per #3. For example:

function make_user(name, age) {     return {         name: name,         age: age,         getName: function() { return name; },         getAge: function() { return age; },     }; }  var user = make_user("Joe", "18"); 
like image 199
Andru Luvisi Avatar answered Oct 05 '22 19:10

Andru Luvisi


If you want to do OOP in JavaScript I'd highly suggest looking up closures. I began my learning on the subject with these three web pages:

http://www.dustindiaz.com/javascript-private-public-privileged/

http://www.dustindiaz.com/namespace-your-javascript/

http://blog.morrisjohns.com/javascript_closures_for_dummies

The differences between 1, 2, and 3 are as follows: 1) Is an example of adding new methods to an existing object. 2) Is the same as #1 except some methods are included in the object in the User function. 3) Is an example of defining an object using JSON. The shortcoming is that you cannot use new (at least not with that example) to define new instances of that object. However you do get the benefit of the convenient JSON coding style.

You should definitely read up on JSON if you don't know it yet. JavaScript will make a lot more sense when you understand JSON.

edit If you want to use new in function #3 you can write it as

function User() {   return {     name: "",     age: 0,     setName: function(name) {       this.name = name;     },     setAge: function(age) {       this.age = age;     },     getName: function() {       return this.name;     },     getAge: function() {       return this.age;     }   }; } 

Of course all of those functions and properties would then be public. To make them private you need to use closures. For example you could make age and name private with this syntax.

function User() {   var age=0;   var name="";   return {     setName: function(name_) {       name = name_;     },     setAge: function(age_) {       age = age_;     },     getName: function() {       return name;     },     getAge: function() {       return age;     }   }; } 
like image 41
Bernard Igiri Avatar answered Oct 05 '22 19:10

Bernard Igiri