0

please clarify the difference b/w this two codes

function Person(gender) {
        this.gender = gender;
        alert('Person instantiated');
    }

    Person.prototype.sayHello = function()
    {
        alert ('hello');
    };

    var person1 = new Person('Male');
    var person2 = new Person('Female');
 // call the Person sayHello method.
    person1.sayHello()

and the second one is below where function define inside funciton (without prototype property)

 function Animal(gender) {
        this.gender = gender;
        alert('animal instantiated');
        this.sayToodle =  function()
        {
            alert ('GOOOOOOO!!');
        };
    }



    var Animal1 = new Animal('Male');
    var Animal2 = new Animal('Female');


    Animal1.sayToodle();
my more simple question are:
  1. what is the difference?
  2. define method inside or out side of a function. what is the effect?
  3. if both same then which is the fine way to define this.
  4. and what does prototype do?

Can we not define method of a obj out side of its function(CLASS)???

HMR
  • 37,593
  • 24
  • 91
  • 160
Mohammad Faizan khan
  • 1,213
  • 3
  • 17
  • 32
  • It has/is/will be asked and answered about twice a week. Maybe this answer can help you out: http://stackoverflow.com/a/16063711/1641941 – HMR Jan 13 '14 at 13:07
  • possible duplicate of [Use of 'prototype' vs. 'this' in Javascript?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – Tibos Jan 13 '14 at 13:14

2 Answers2

3

Defining a member inside the constructor (such as: this.name) gives only that instance of the object access to that member.

Defining a member inside the prototype allows all instances to "share" that property.

A way that helped me understand this was to define an array (or any other member that is not a method) inside the prototype, like so:

function Animal() {}

Animal.prototype = {
    kids: [],
    giveBirth: function() {
        for(var i = 0; i < arguments.length; i++) {
            this.kids.push(arguments[0]);
        }
    }
}

var cat = new Animal();
var giraffe = new Animal();

cat.giveBirth('kitten','another kitten','yet another kitten');

// cat.kids === ['kitten','another kitten','yet another kitten'];
// giraffe.kids === ['kitten','another kitten','yet another kitten'];

If you notice, the giraffe's kids were set (as kittens). Why is this? Because in this case, .giveBirth() accesses the prototype's kids array, which is shared by all instances.

What if we don't want to share the members, because the members are unique? You can do like so:

function Animal() {
    this.kids = [];
}

Animal.prototype = {
    giveBirth: function() {
        for(var i = 0; i < arguments.length; i++) {
            this.kids.push(arguments[0]);
        }
    }
}

var cat = new Animal();
var giraffe = new Animal();

cat.giveBirth('kitten');

// cat.kids === ['kitten']
// giraffe.kids == undefined

giraffe.giveBirth('baby giraffe');

// cat.kids === ['kitten']
// giraffe.kids === ['baby giraffe']

As you pointed out in the comments, part of how you decide to define the properties plays into memory usage; another part plays into what members you want to be "shared" across all instances.

To get a little more insight into prototypes (through understanding how new works), see What is the 'new' keyword in JavaScript?, on StackOverflow.

Here's a quote from there:

After a lot of searching, I have finally found out exactly what the new keyword does, and it is 4 things:

  1. It creates a new object. The type of this object, is simply object.
  2. It sets this new object's internal, inaccessible, [[prototype]] property to be the constructor function's external, accessible, prototype object.
  3. It executes the constructor function, using the newly created object whenever this is mentioned.
  4. It returns the newly created object, unless the constructor function returns a non-primitive value. In this case, that non-primitive value will be returned.
Community
  • 1
  • 1
Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • JavaScript has no inherent notion of private and public, but it seems to me that the method sayToodle is accessible from anywhere, so it is definitely not private. – Tibos Jan 13 '14 at 13:07
  • No, JavaScript doesn't have private variables. Definining members in a constructor with `var something=...` makes the variable available through closure. – HMR Jan 13 '14 at 13:09
  • @HMR that doesn't seem to be the question, though. It could be part of a larger answer, like the one you linked to, explaining why someone would want to have a function copied to every instance. – Tibos Jan 13 '14 at 13:12
  • 1
    @Tibos basically copied the intro of the long answer here. Will add a link to the long answer as prototype and constructor functions can not easily be explained in a couple of lines. – HMR Jan 13 '14 at 13:16
  • so there is two main difference concluded from you answer (1) public private (2) memory consumption. isnt it?? – Mohammad Faizan khan Jan 13 '14 at 14:17
  • Yes I believe so. As pointed out, there aren't really public and private members, but "shared" and "not shared". The "shared" members (inside the prototype) are not copied to each instance, whereas the "not shared" members defined in the constructor **are** copied to each instance, making them unique. – Josh Beam Jan 13 '14 at 14:31
0

Prototype members are shared among instances and members in the constructor function defined as this.something are instance specific.

When an instance need instance specific members (like Person.name) define it as this.name. When it can be shared (like a method sayName) define it on the prototype like: Person.prototype.sayName=function(){...

For more info on prototype and constructor functions you can check this answer.

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • it means using prototype we save memory plus provide sharing of function's members across the instance. so there is two difference?. – Mohammad Faizan khan Jan 13 '14 at 14:20
  • @MohammadFaizankhan Correct, adding to the prototype will affect already created instances too where when it's instance specific it would not. – HMR Jan 13 '14 at 15:15