-2

1

 function Student() {
    // initialization
    }

2

var student = function(){
// initialization
};

what will be the prototype value in case of 1 and 2. Thanks.

for the first case i am getting Student and for 2nd i am getting Object. Why?

Trying
  • 14,004
  • 9
  • 70
  • 110
  • 1
    Both ways to declare the constructor are equivalent. Both constructors get a default prototype object. – Edwin Dalorzo Mar 16 '14 at 14:37
  • How exactly are you getting `Student` and `Object` from them? What is your test? And, note that the 2nd example is a referenced, but anonymous constructor. `var Student = function Student() {};` would name it as well. – Jonathan Lonowski Mar 16 '14 at 14:47
  • possible duplicate of [var functionName = function() {} vs function functionName() {}](http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname). There is no difference in regard to the prototype. – Bergi Mar 16 '14 at 14:48
  • @JonathanLonowski i am putting `console.log(Object.getPrototypeOf(new Student()));` inside javascript console of google chrome. – Trying Mar 16 '14 at 14:49
  • @Bergi it is not duplicate. I am asking how the `prototype` is different for these two. Please consider again. Thanks. – Trying Mar 16 '14 at 14:51
  • @Trying: Is it then an exact duplicate of [Difference between prototype structure of named and anonymous function in javascript?](http://stackoverflow.com/q/22435645/1048572) – Bergi Mar 16 '14 at 14:55

3 Answers3

1

You can easy see the prototypes of the objects by:

var s = new Student();
Object.getPrototypeOf(s);

and

Object.getPrototypeOf(student);

In the first case (constructor function), you can change the default prototype value by:

Student.prototype = { foo: 'bar' };
var s = new Student();
Object.getPrototypeOf(s); // { foo: 'bar' }

In the second case:

var student = Object.create({ foo: 'bar' });
student.prop = 'val';
Object.getPrototypeOf(student); // { foo: 'bar' }

Why they differ?

You can see the exact algorithm used for creating objects with constructor function here. Basically:

  1. Create a new native ECMAScript object and let F be that object.
  2. Set all the internal methods, except for [[Get]], of F as described in 8.12.
  3. Set the [[Class]] internal property of F to "Function".
  4. Set the [[Prototype]] internal property of F to the standard built-in Function prototype object as specified in 15.3.3.1.
  5. ...

According to the standard:

The production ObjectLiteral : { } is evaluated as follows:

Return a new object created as if by the expression new Object() where Object is the standard built-in constructor with that name.

Which means that when {} is used the internally should be called new Object, which means that you will have Object as default prototype (see the reference above).

Minko Gechev
  • 25,304
  • 9
  • 61
  • 68
  • Is it not simpler to just do `Student.prototype`? After all that is prototype the instances are going to get, isn't so? – Edwin Dalorzo Mar 16 '14 at 14:39
  • Yep, it is basically the same but I believe that it will be easier to show the different prototypes by pointing the prototypes for the object instances. – Minko Gechev Mar 16 '14 at 14:40
  • for the first case i am getting Student and for 2nd i am getting Object. Why? – Trying Mar 16 '14 at 14:41
  • whats student.prop = 'val' about? – dewd Mar 16 '14 at 14:42
  • In the first case `Object.getPrototypeOf(s)` would be equal to `Student.prototype`, as @EdwinDalorzo stated above. – Minko Gechev Mar 16 '14 at 14:42
  • @dewd showing how you can "extend" the base object. – Minko Gechev Mar 16 '14 at 14:43
  • for second case. what about first case? – dewd Mar 16 '14 at 14:44
  • What about `Object.getPrototypeOf(new student)` and `Object.getPrototypeOf(Student)`? I don't think the lowercase naming means it won't be used as a constructor. – Bergi Mar 16 '14 at 14:49
  • According to the `jshint` conventions lower first case means that the function is not a constructor. But `new student` and `Student` differs a lot. In the example above `student` is not even defined. While `Student` is a function, when called `Student` it will return undefined. – Minko Gechev Mar 16 '14 at 14:53
  • @EdwinDalorzo I believe that I answer your question with the included quotes from the ECMAScript specification. – Minko Gechev Mar 16 '14 at 15:02
1

i am putting console.log(Object.getPrototypeOf(new Student())); inside javascript console of google chrome.


The difference is that the 2nd example is an anonymous constructor.

function Student() {}
console.log(Student.name); // "Student"

var Student = function () {};
console.log(Student.name); // ""

The var Student doesn't name it, only references it. But, it can be named as well:

var Student = function Student() {};=
console.log(Student.name); // "Student"

Regardless, instances of each are still recognized as Students:

console.log(new Student() instanceof Student); // true for both

But, Chrome is trying to be more informative, so it's following the prototype chain until it finds a name it can display:

var Student = function () {};

var base = Object.getPrototypeOf(Student.prototype);

console.log(base.constructor === Object); // true
console.log(base.constructor.name);       // "Object"
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
0

There is a lot of material out there explaining how prototypes work. In your example above, you are declaring two constructors that are equivalent. That is, you could create objects of type 'Student' out of your two constructors.

For example, I can either do:

function Student() {
    // initialization
}
var pascal = new Student();

Or I could do

var Student = function(){
// initialization
};
var pascal = new Student();

The result is the same.

Now, these constructors have a prototype object. They get one by default if you do not assign one to them. For instance, in either case I can do:

Student.prototype.getName = function(){
  return this.name;
};

And then any of my student instances could something like:

pascal.getName();

However, you could create you own prototype objects and assign them directly, in case you would like to expose something through them to all instances of a given constructor. For instance.

You could say that the prototype of Student is another object.

Student.prototype = {
   takeExam: function(){
      //define take exam
   },
   constructor: Student
};

And now this synthetic object is the prototype of the Student constructor.

Or you could even define a type hierarchy with this, like in this example:

function FlyingThing(){ };

FlyingThing.prototype.fly = function(){
   //fly
};

function Bird(){ }

Bird.prototype = new FlyingThing();
Bird.prototype.walk = function(){
  //walk
};

Now, every instance of Bird can both fly and walk.

Now, it is important to distinguish between a constructor prototype and and instance prototype. As I have already shown, you have direct access the constructor prototype and you can easily change that, add new stuff to it, or change it in anyways you find appropriate.

When an instance is created for a given constructor, it gets assigned a prototype object based on the constructor you used to create it. That prototype is not so readily accessible. That prototype is the one that JavaScript will use in property lookups.

If you want to know what is the prototype of a given instance object you need to use the Object.getPrototypeOf and Object.isPrototypeOf methods as shown in other answer.

The prototype of an instance of Student should logically be the Student.prototype object that you defined for the Student constructor.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205