5

These are the ways of creating javascript objects:

function apple(optional_params) {
    this.type = "macintosh";
    this.color = "red";
    this.getInfo = function () {
        return this.color + ' ' + this.type + ' apple';
    };
}

var apple = {
    type: "macintosh",
    color: "red",
    getInfo: function() {
        return this.color + ' ' + this.type + ' apple';
    }
}

I really prefer the latter one most since it's Json syntax, but I've seen more of the first one than the latter one.

  • Are there any differences between them functionally?
  • Could each of them be extended, inherited and cloned/copied?
  • In the latter one I could easily create nested elements, is this possible with the first one?
  • In the latter one I can't pass optional parameters?
  • Are they serving different purposes? If yes, could you give scenarios where I would use either of them.
2
  • 4
    No, it's not JSON syntax, it's an object literal. JSON is a text format that is a subset of Javascript object literal syntax. Commented Sep 24, 2010 at 6:48
  • 1
    json also doesn't support functions Commented Sep 24, 2010 at 6:51

5 Answers 5

3

The difference is that you can reuse the first one. Example:

function Apple(type, color) {
  this.type = type;
  this.color = color;
  this.getInfo = function () {
    return this.color + ' ' + this.type + ' apple';
  }
}

var red = new Apple("Macintosh", "red");
var green = new Apple("Granny Smith", "green");

vs.

var red = {
  type: "Macintosh",
  color: "red",
  getInfo: function() {
    return this.color + ' ' + this.type + ' apple';
  }
};

var green = {
  type: "Granny Smith",
  color: "green",
  getInfo: function() {
    return this.color + ' ' + this.type + ' apple';
  }
};
Sign up to request clarification or add additional context in comments.

2 Comments

Isn't it possible to pass parameters to the second one somehow?
@ajsie: You could wrap the object literal in a function and pass parameters to the function that you use in the object. That's used sometimes when you want a factory function rather than a constructor.
3

For your first object you'd want to put the member function in the prototype, like such:

function apple(optional_params) {
    this.type = "macintosh";
    this.color = "red";
}

apple.prototype.getInfo = function () {
    return this.color + ' ' + this.type + ' apple';
}

This causes the "object" to only create two new fields in memory (type and color) while keeping the function as part of the prototype for that object. Your second object (hash table) creates a new function for each object.

So as you can see using the function approach is good if you have lots of functions, because the functions then don't take up extra memory.

To clarify: Your two examples produce the same result, but if you put the function in a prototype the result is different.

2 Comments

Can't I do the same for the second one, only have the attributes in that json string but then insert them afterwards with: "apple.getInfo = function() {...}"?
note the prototype bit. and yes, it is possible, as long as you also create a constructor for it. (the function-object itself is a constructor by default when using the new keyword)
2

This is the way I create Javascript objects in most cases:

/**
 * This becomes the constructor of Apple, a type of fruit.
 */
 var Apple = function() {
    // Object init here
    // This becomes a "private" variable
    var seeds = 50;

    // This becomes "public" properties
    this.color  = 'red';
    this.weight = 100; // in grams if you wonder. 

    /**
     * Do stuff to count the seeds
     * This becomes a privileged method that can access private variables
     * and be called from outside the object
     */
    this.countSeeds = function() {
        // Do stuff to count the seeds.
        return seeds;
    }
}

/**
 * Static functions can be utility functions that can be called separate from 
 * object instances. They do not have access to any variables or functions
 * in the constructor.
 */
Apple.getTypes = function() {
    return ['golden', 'granny', 'red', 'pink'];
}

/**
 * Public function that gets the default color
 */
Apple.prototype.getColor = function() {
    return Apple.color;
} 

/**
 * Public function that sets the color of the object instance.
 */
Apple.prototype.setColor = function(color) {
    this.color = color;
    return this.color;
}

var golden = new Apple();
golden.setColor('yellow');
alert('The color of the apple is ' + golden.color);

3 Comments

I think you forgot the quotes around "red". And the Apple.getColor() doesn't work. It returns "undefined". Why is that?
Sorry about that. Static functions are called outside object instances and naturally do not have access to object internals and variables set by the constructor. my bad. I wrote the example without checking.
Is Apple name of a class or name of an object ? looks like class is Apple and object is golden
2

The second example simply defines an instance of Object, with a few properties set. The first one is much more interesting.

Functions in JavaScript have dual purposes, one as a normal function/procedure, and the other as the basis for prototypal inheritance, similar to a "class" in normal OOP.

For example:

var apple = function() {
    this.type = 'granny smith';
};
var myApple = new apple();
alert(myApple.type); // -> 'granny smith'

Here, we've defined a "class" called apple, with an initializer that sets the type property. myApple is then created as an instance of apple, and the type property gets set by the apple() initializer.

(As an aside, new apple() could also be called as new apple with the parenthesis omitted and the result is still the same, the initializer is still called, it just receives no arguments)

The other major thing that using new gives us is prototypal inheritance. All functions come with a prototype object that we can set properties on. Those properties then become fallback values for instance objects that don't have their own value defined.

Example:

var greenApple = function() { };
var myApple = new apple();
alert(myApple.color); // -> undefined
greenApple.prototype.color = 'green'
alert(myApple.color); // -> green

Here, setting greenApple.prototype.color affected the color property for the myApple we had already created. This is what is referred to as prototypal inheritance, and it has a wide variety of uses.

 

Edit: The following refers to an earlier version of the question that was edited while I was writing this. You can safely ignore it unless you're especially interested.

Now, back to your first example:

var apple = new function() { ... }

Because you have the new keyword before the function definition, the effect is like creating the apple class, making a myApple object, then throwing the apple class away. If you had access to this class, you could use .prototype to add prototype properties, but you don't - all that's contained in the apple variable (in OOP terms) is an instance of the class, not the class itself.

Comments

0

Sorry, I'm still a little noob at javascript, but aren't these functions and not objects? Object-oriented, yes, but functions? Quite interested actually.

Oh, I've only used the first one. I think it looks clearer to me because it outright declares "new function".

3 Comments

Put this as a comment and I'm sure you'll get answers:)
In JS, a Function is a kind of Object
Actually most everything become an object. [] = Object, {} = Object, function() {} = Object. It's a very flexible model and opens up some pretty interesting possibilites.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.