Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Learning .prototype

Tags:

javascript

Edit: for those people seeing this post in the future, this site was undoubtedly critical for me to digest Javascript. If you're coming from a traditional OOP background, I HIGHLY recommend it. The UML-esq diagrams were amazing.

I still can't get my head around what the .prototype property in Javascript is. Is it simply a reference to another object? Or is it a reference to a pointer to another object? I come from C/C++/x86 and just can't see how it works. Let's look at some examples of how I currently see things; it'd help to point out my errors to see how things work. I don't even know if some of these are valid syntax. Object and Function are the global object/function objects respectively.

1                                        // Global.prototype = ??
2                                        // Function.prototype = ??
3 
4   var obj1 = {};                       // obj1.prototype = Object 
5   obj2 = {};                           // obj2.prototype = Object
6
7   var func1 = function() {};           // func1.prototype = Function
8   func2 = function() {};               // func2.prototype = Function
9   function func3() {}                  // func3.prototype = Function  
10

I'm so confused.

11  var Foo = function() { this.prop1 = 0; }
12  var foo = new Foo();                 // should it be 'new Foo' or 'new Foo()'?
13  // Foo.prototype = Function
14  // foo.prototype = Foo
15  var Goo = function() { this.prop2 = 0; }
16  var goo = new Goo();
17  // goo.prototype = Goo
18  goo.prototype = new Foo();
19  // goo.prop1 now exists ?

I also don't understand swapping prototypes around.

20  function A () {
21     this.prop1 = 1;
22  }
23  function B () {
24     this.prop2 = 2;
25  }
26  function C () {
27     this.prop3 = 3;
28  }
29  C.prototype = new B();
30  var c = new C();
31  // c.prop1 = 1
32  // c.prop2 = 2
33  // c.prop3 = undefined
34  C.prototype = new A();
35  // c.prop2 = 2???
36  // c.prop3 = 3

I can't get a grasp on the concept. I don't quite understand. I don't get how cloned objects get their own local copies of data, but changes to the original object (the prototype) somehow cascade down to the clones. I've been fiddling around with FigureBug trying things out, but mentally I can't come up with an idea that is consistent with every example ive seen

C++ may be a huge monstrosity, but at least I know exactly what's going. Here... I'm using my best guess.. Just a new paradigm I suppose. Anyways, thanks if you can help out... I'm turned upside-down on this .prototype.

like image 662
gone Avatar asked Jul 15 '13 17:07

gone


People also ask

What is a learning prototype?

A prototype learning system is a system of cognitive processes together with their underlying neural structures that enables one to learn (extract) a category prototype from a set of exemplars.

What is a prototype example?

Some of the examples of prototypes are wireframes, slides, landing pages, working models, an interactive frontend, and videos.

What is the example of e-learning?

E-learning platformsMOOCs (Massive Online Open Courses), e.g. Coursera or Futurelearn. Virtual learning environment (VLE), such as Learn or Blackboard. Video streaming services, such as YouTube. Virtual instructor-led training (VILT), e.g. WebEx or webinars.

What is rapid prototyping in education?

What is Rapid Prototyping? Rapid Prototyping is an instructional design approach that combines the design, developmental, and evaluation phases. It is a non-linear approach that produces a sample working model that is a scaled-down representative version of the whole course.


2 Answers

Wow, that's a lot of questions. Let's work through them.

Is it simply a reference to another object? Or is it a reference to a pointer to another object?

There are no pointers in JavaScript. Yet, a variable or property holding "an object" is actually holding a reference to the object, so other variables can hold references to the same object.

Global.prototype = ??

The global object (window if you want), where all global variables are defined, has no prototype (don't care about exceptions in some environments).

I still can't get my head around what the .prototype property in Javascript is.

The .prototype property is a property that all function objects have, pointing to their prototype object (a plain object).

You must not confuse it with the internal prototype reference which each object has. That prototype points to the object where properties are looked up which an object doesn't have itself.

Function.prototype = ??

This is the object from which all Function objects inherit. It contains things like call or bind.

var obj1 = {};              // obj1.prototype = Object
var func1 = function() {};  // func1.prototype = Function

Yes, kinda. I think you've got the concept, but didn't know the terminology. While func.prototype is a different thing, the obj.prototype property doesn't even exist. However, you meant the internal prototypes - we can access them via the Object.getPrototypeOf function. And they don't refer to the constructor functions, but their prototype objects. Here's the correction:

Object.getPrototypeOf(obj1) === Object.prototype
Object.getPrototypeOf(func1) === Function.prototype

should it be 'new Foo' or 'new Foo()'?

That doesn't matter, they're equivalent. You only need the brackets explicitly when you want to pass arguments.

var Foo = function() { this.prop1 = 0; }
var foo = new Foo();

Again, your assumptions were correct but expressed wrong. Let's work through the details.

Above, I've talked about "prototype objects". What are those? They are plain objects which get implicitly created with every function. In this case, it's Foo.prototype - an empty object. So we deal here with three objects: The Foo constructor function, its Foo.prototype prototype object and the foo instance.

What's special about foo? It's the first thing which the new operator does. When a function is getting invoked as a constructor - with new - then its .prototype property is accessed and a new object is instantiated with its internal prototype set to that prototype object. That's the miraculous thing. After that the function is called on the new instance so that this is the new object; and in your case it creates the .prop1 property on the instance. Then the result is returned (and assigned to foo).

How to make use of that magic now? The point is to create properties on the prototype object, which will be inherited then.

// modify `Foo.prototype`, the object which `foo` inherits from:
Foo.prototype.prop2 = 1;
console.log(foo.prop2); // 1!

I also don't understand swapping prototypes around.

The problem is that this is quite impossible. Once instantiated, an object's prototype chain is quite static. However, you don't need that often.

goo.prototype = new Foo();

That didn't work because the .prototype property is not what you expected.

var c = new C();
C.prototype = new A();

That does work only a littlebit. Have a look above at what new does - it looks up the .prototype property of the constructor only once. The internal prototype stays locked then - you don't change the c instance. However, if you would create a new instance var d = new C() now then it would inherit from the A instance.

I hope this helps; if you have further questions please comment.

like image 129
Bergi Avatar answered Nov 15 '22 00:11

Bergi


The prototype is used to search properties when the object itself doesn't have it defined, during reads. Writes always happen on the object itself

When you call

// An instance of Foo ({prop1:0}) is set as the 
// prototype (to all instances of Goo)
var goo = new Goo();

// 0, from the prototype
console.log(goo.prop1); 

// Read from the object itself (set in Goo's constructor)
console.log(goo.prop2); 

// New instance, same prototype as goo
var goo2 = new Goo();
console.log(goo2.prop1) ; // 0, still from the prototype

// Setting is always at the object level, not the prototype
goo.prop1 = 5;

// goo2 is still reading from the prototype
console.log(goo2.prop1); 

N.B.

Don't instantiate the parent class just to setup inheritance. See why here http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

like image 26
Juan Mendes Avatar answered Nov 15 '22 00:11

Juan Mendes