I think the difference has clicked in my head, but I'd just like to be sure.
On the Douglas Crockford page Prototypal Inheritance in JavaScript, he says
In a prototypal system, objects inherit from objects. JavaScript,
however, lacks an operator that performs that operation. Instead it
has a new operator, such that new f() produces a new object that
inherits from f.prototype.
I didn't really understand what he was trying to say in that sentence so I performed some tests. It seems to me that the key difference is that if I create an object based on another object in a pure prototypal system, then all the parent parent members should be on the prototype of the new object, not on the new object itself.
Here's the test:
var Person = function(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.toString = function(){return this.name + ', ' + this.age};
// The old way...
var jim = new Person("Jim",13);
for (n in jim) {
if (jim.hasOwnProperty(n)) {
console.log(n);
}
}
// This will output 'name' and 'age'.
// The pure way...
var tim = Object.create(new Person("Tim",14));
for (n in tim) {
if (tim.hasOwnProperty(n)) {
console.log(n);
}
}
// This will output nothing because all the members belong to the prototype.
// If I remove the hasOwnProperty check then 'name' and 'age' will be output.
Is my understanding correct that the difference only becomes apparent when testing for members on the object itself?
Your assumptions are correct, but there is another pattern that Douglas doesn't talk much about - the prototype can be used for properties as well. Your person class could have been written as:
var Person = function(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.name = null; //default value if you don't init in ctor
Person.prototype.age = null;
Person.prototype.gender = "male";
Person.prototype.toString = function(){return this.name + ', ' + this.age;};
In this case, iterating over properties of an instance of this class, as you do in your example, would generate no output for the 'gender' property.
EDIT 1:
The assignment of name and age in the constructor do make the properties visible by hasOwnProperty (thanks #matt for reminding me of this). The unassigned gender property would not be visible until someone sets it on the instance.
EDIT 2:
To further add to this, I present an alternative inheritance pattern - one that I have personally used for very large projects:
var inherits = function(childCtor, parentCtor) {
function tempCtor() {};
tempCtor.prototype = parentCtor.prototype;
childCtor.superclass = parentCtor.prototype;
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};
var Person = function(name){
this.name = name;
}
Person.prototype.name = "";
Person.prototype.toString = function(){
return "My name is " + this.name;
}
var OldPerson = function(name, age){
OldPerson.superclass.constructor.call(this);
this.age = age
};
inherits(OldPerson, Person);
OldPerson.prototype.age = 0;
OldPerson.prototype.toString = function(){
var oldString = OldPerson.superclass.toString.call(this);
return oldString + " and my age is " + this.age;
}
This is a fairly common pattern with a small twist - the parent class is attached to the child via the "superclass" property permitting you to access methods/properties overridden by the child. Technically, you could replace OldPerson.superclass with Person, however that is not ideal. If you ever changed OldPerson to inherit from a class other than Person, you would have to update all references to Person as well.
EDIT 3:
Just to bring this full circle, here is a version of the "inherits" function which takes advantage of Object.create and functions exactly the same as I previously described:
var inherits = function(childCtor, parentCtor) {
childCtor.prototype = Object.create(parentCtor.prototype);
childCtor.superclass = parentCtor.prototype;
};
EDIT: This answer was originally a response to #jordancpaul's answer, which he has since corrected. I will leave the portion of my answer that helps explain the important difference between prototype properties and instance properties:
In some cases, properties are shared between all instances and you need to be very careful whenever you're declaring properties on the prototype. Consider this example:
Person.prototype.favoriteColors = []; //Do not do this!
Now, if you create a new Person instance using either Object.create or new, it doesn't work as you might expect...
var jim = new Person("Jim",13);
jim.favoriteColors.push('red');
var tim = new Person("Tim",14);
tim.favoriteColors.push('blue');
console.log(tim.favoriteColors); //outputs an array containing red AND blue!
This doesn't mean you can't ever declare properties on the prototype, but if you do, you and every developer who works on your code needs to be aware of this pitfall. In a case like this, if you prefer declaring properties on the prototype for whatever reason, you could do:
Person.prototype.favoriteColors = null
And initialize it to an empty array in the constructor:
var Person = function(name, age) {
...
this.favoriteColors = [];
}
The general rule when using this method is that default values for simple literal properties (strings, numbers, booleans) can be set on the prototype directly, but any property that inherits from Object (including arrays and dates) should be set to null and then initialized in the constructor.
The safer way is to only declare methods on the prototype, and always declare properties in the constructor.
Anyway, the question was about Object.create...
The first argument passed to Object.create is set as the prototype of the new instance. A better usage would be:
var person = {
initialize: function(name, age) {
this.name = name;
this.age = age;
return this;
},
toString: function() {
return this.name + ', ' + this.age;
}
};
var tim = Object.create(person).initialize("Tim",14);
Now the output will be the same as in your first example.
As you can see, it's a different philosophical approach from the more classical style of OOP in Javascript. With Object.create, the emphasis is on creating new objects from existing objects, rather than on the constructor. Initialization then becomes a separate step.
Personally I have mixed feelings about the Object.create approach; it's very nice for inheritance because of the second parameter that you can use to add additional properties to an existing prototype, but it also is more verbose and makes it so instanceof checks no longer work (the alternative in this example would be to check person.isPrototypeOf(tim)).
The main reason I say Object.create is verbose is because of the second parameter, but there are some useful libraries out there that address that:
https://github.com/Gozala/selfish
https://github.com/Raynos/pd
(and others)
I hope that was more enlightening than confusing!
Related
What is an instance in JavaScript? Can anyone provide an example please?
Also, please explain your code.
An instance is simply an object that was created by a class (ES6) or constructor function. Here's an example:
function Person(name) {
this.name = name;
}
var john = new Person("John Doe");
console.log(john);
//john is an instance of Person - we can see this by using the instanceof operator
console.log(john instanceof Person);
JavaScript makes instances when defining variables, but these are only accessible by using typeof unless you explicitly use the new constructor to make your variable:
var str = "Foo Bar";
var num = 123;
var bool = true;
var obj = { abc: "def" }
var arr = [true, 1, "s"];
console.log(typeof str);
console.log(typeof num);
console.log(typeof bool);
console.log(typeof obj);
console.log(typeof arr);
console.log(typeof undefined);
console.log(typeof null);
There are a couple of tricks with typeof though - typeof [] == "object" because an array is an object with a few different methods. The other most common issue is typeof null == "object", because of a discrepancy when JavaScript was created between null and undefined.
If you want to find the constructor of any value, use constructor.name:
var str = "Foo Bar";
var num = 123;
var bool = true;
var obj = { abc: "def" }
var arr = [true, 1, "s"];
console.log(str.constructor.name);
console.log(num.constructor.name);
console.log(bool.constructor.name);
console.log(obj.constructor.name);
console.log(arr.constructor.name);
This trick also works with your own constructors and classes:
function Person(name) {
this.name = name;
}
var john = new Person("John Doe");
console.log(john.constructor.name);
When you create an object !
Example:
//instancing a image
var myImage = new Image(100, 100);
//Append in to body
document.querySelector("body").appendChild(myImage);
Simply put, in object-oriented programming, there are classes and objects. When you instantiate, or create an instance of a class, you get an object.
For example, take the following Car class:
function Car(myVin) {
this.vin = myVin;
}
let myHonda = new Car(“24A6733HJ42983C55”);
let myFord = new Car(“JJ67100473KL93228”);
let momsMinivan = new Car(“JF293HJL679904611”);
You just instantiated the Car class three times. Each is an instance.
ES2015 (aka ES6) introduces the class keyword, and constructors:
class Car {
constructor(myVin) {
this.vin = myVin;
}
}
This gets much more involved.
IMO, If you really want to learn OO programming, it’s really best to learn the C++ way first. There you’ll see classical inheritance at work, with concepts of constructors, private, protected, and public data members, design patterns, and other key concepts. This will build a solid foundation before you dive into the kluge that is Ecmascript classical inheritance.
Under the hood, Javascript has prototypical inheritance; Ecmascript plasters classical inheritance on top. It’s is a little weird and hacky, and have to do strange things with closures to achieve privacy.
See link below for a good lesson on OOP in C++.
https://m.youtube.com/watch?v=vz1O9nRyZaY
Let there be an object with properties id, name, and age. Now you want to create 100
objects that represent 100 people. Each person will have an id, name, and age.
You can create objects like:
var person1 = {
id: 1,
name: “p1”,
age: 20
};
var person2 = {
id: 2,
name: “p2”,
age: 21
};
….. And so on.
But instead of creating 100 objects by individually defining id, name, and age for all of
them, you create a standard template with properties id, name, and age. Then use
this template to create objects and set the required values.
This standard template can be seen as an object. Each time you create a new
object by using the new keyword, you create a new instance of an already-defined object with already-specified
properties.
For that, you can do this:
function people(id, name, age){
this.id = id;
this.name = name;
this.age = age;
}
let people1 = new people(1,'rani',20);
let people2 = new people(2,'rahul',21);
let people3 = new people(3,'adi',20);
.
.
.
and so on.
Here people1, people2, and people3 are the instances.
function Person(name, age, height) {
this.name = name,
this.age = age,
this.height = height
}
var john = new Person("John", 24, 175);
What I read should be avoided:
john.__proto__.fact = "I am a humanly human!"
What should be done instead:
Person.prototype.fact = "I am a humanly human!"
If you want to add to the prototype of the object john refers to, doing so through john.__proto__ gives the impression to the reader of the code that this change is specific to john somehow, which it isn't; it affects all objects that use that prototype (current and future). Using Person.prototype doesn't give that impression, it correctly indicates what you're doing.
Separately, note that not all objects (not even all objects with prototypes) have __proto__, because __proto__ is inherited from Object.prototype, but not all objects inherit from Object.prototype. For that reason, in new code, it's best to avoid __proto__ entirely; use Object.getPrototypeOf instead if you need to get the prototype of an object: Object.getPrototypeOf(john).
In a comment you've answered the question of why you'd want to do this with:
To add methods such that they are not present in every Person object you create.
...but that's exactly what adding to john.__proto__ would do: Add the method to every Person object (indirectly through the prototype), current and future, exactly like adding to Person.prototype — because those (and Object.getPrototypeOf(john)) are all just different ways of getting to the same object:
function Person(name) {
this.name = name;
}
var john = new Person("John");
console.log(john.__proto__ === Person.prototype); // true
console.log(Object.getPrototypeOf(john) === Person.prototype); // true
var paul = new Person("Paul");
john.__proto__.someNewMethod = function() {
console.log(this.name);
};
john.someNewMethod(); // "John"
paul.someNewMethod(); // "Paul"
If you want to add a method just to the object john refers to, don't use __proto__ or Person.prototype at all: Just do:
john.niftyMethod = function() { /*....*/ };
I have a question in regards to classical inheritance vs prototypical inheritance. I wanted to see what is better?
Let's say we have a function called familyTree.
function familyTree(){
this.lastname = "xyz";
}
If i want to add any additional details for them as far as I read, we can inherit parent in two ways:
1: prototypical way:
familyTree.prototype.personDetails = function(){
this.firstName = "abc";
this.middleName = "middle1";
var newToString = function(name){ //overwriting toString method
console.log("The name is: "+name+"Middle Name is "+middleName);
}
}
2: Classical way using 'new' keyword
var newPerson = new familyTree();
newPerson.firstName = "abc";
newPerson.middleName = "middle1";
newperson.newToString = function (name){
console.log("The name is: "+name+"Middle Name is "+middleName);
}
Let's say if I want to create 100 different middle names.
What makes more sense? Using Classical Inheritance or Prototypical? Because using Classical can copy over all the objects but using prototypical can get everything messy.
Please illustrate, when one should be using classical vs prototypical.
There is only one kind of inheritance in JavaScript and that is prototypical inheritance. "Classical" inheritance doesn't exist in JavaScript.
Despite the "syntactic sugar" that the JavaScript language has to make OOP developers who are very comfortable with class-based programming feel at home (including the class keyword), JavaScript doesn't actually have or use classes. That language vocabulary is just meant to make you feel all warm and fuzzy.
Your question is not actually asking about inheritance, it's asking about whether properties should be attached to the constructor function or the prototype.
See the code comments for explanations:
// When you create a function that you will use to create object instances,
// you have a "constructor function". By convention, these functions should
// be named in PascalCase as a way to let others know that they are to be
// used in conjunction with the "new" keyword as a constructor.
function FamilyTree(first, middle, last){
// Because this function will be used to create instances of a
// FamilyTree object, each instance created will need to store
// data that is different from another. This is done with "instance
// properties" and they are created by prepending the property name
// with "this.". The "this" object will be referenced by the object
// instance variable that is used when the instance is created:
this.firstName = first;
this.middleName = middle;
this.lastName = last;
}
// JavaScript objects don't technically have "methods" - - they
// have properties that store functions and functions are how
// to add behavior to an object. Since the behaviors of an object
// don't typically change from instance to instance, you should not
// add them to the constructor function. If you did, the code would
// work, but each instance would need to store a copy of the exact
// same behavior, making the objects unnecessarialy large in memory.
// Instead, we attach behaviors that all instances of an object will
// need to the prototype of the constructor and that way all instances
// created from the constructor will inherit the behaviors, but the
// acutal behavior will only be stored once, thus saving on memory space
// and eliminating the possibility of one instance behaving differently
// than others, unintentionally.
// Implementing "methods" that all FamilyTree instances will inherit:
FamilyTree.prototype.newToString = function(name){
return "First name: " + this.firstName + ", Last Name: " + this.lastName;
}
// The constructor function's prototype (as with all objects) derives from "Object"
// which defines a "toString" property, by re-defining that property on the constructor's
// prorotype, we will be able to override the inherited one
FamilyTree.prototype.toString = function(name){
return this.lastName + ", " + this.firstName;
}
// To use this object, we have a few choices, but the simplest one is to just instantiate it:
var myFamilyTree = new FamilyTree("John","Fitzgerald","Kennedy");
// Now, we just work with the instance:
console.log(myFamilyTree.firstName);
console.log(myFamilyTree.middleName);
console.log(myFamilyTree.lastName);
console.log(myFamilyTree.newToString());
console.log(myFamilyTree.toString());
Now, the above code works, but is technically not organized well since the object is a "Family Tree" and all it really stores is a single person's name and some ways to output that name. Not much of a family tree. In reality, this "Family Tree" object should be made up from other objects (i.e. many individual people should be able to be included along with other pertinent family tree data). If we apply the OOP "Single Responsibility Principle" ("A class/module should have only one reason to change"), we would need to make the Family Tree object have smaller object parts. All this would involve is making the original object have a property that stores an array of people objects:
// First, make objects that represent the parts of the whole
function Person(first, middle, last, dob, maiden){
// Instance properties are added to the constructor, which makes individual instances:
this.firstName = first;
this.middleName = middle;
this.lastName = last;
this.dob = dob;
this.maidenName = maiden;
}
// Behavior properties are added to the constructor's prototype to avoid duplication
// of code across instances:
Person.prototype.newToString = function(name){
return "First name: " + this.firstName + ", Last Name: " + this.lastName;
}
Person.prototype.toString = function(name){
return this.lastName + ", " + this.firstName;
}
// Then create an object that becomes the sum of the parts:
function FamilyTree(){
// We just need a way to store family members.
// Each FamilyTree instance can have different members, so an instance property
// is needed:
this.people = [];
}
// And, again, behaviors are added to the prototype:
FamilyTree.prototype.getMemberCount = function(){
return this.people.length;
}
FamilyTree.prototype.addMember = function(personObject){
this.people.push(personObject);
}
FamilyTree.prototype.removeMember = function(personObject){
var index = this.people.findIndex(function(element){
return personObject === element;
});
this.people.splice(index, 1);
}
// And, because the tree stores an array, we can looop through it:
FamilyTree.prototype.enumerate = function(){
var result = "";
this.people.forEach(function(person){
result += person.firstName + " " + person.middleName + " " + person.lastName +
" (" + person.newToString() + " [" + person.toString() + "])";
});
return result;
};
// Now, to use the Family Tree, we first need some people
var jack = new Person("John","Fitzgerald","Kennedy", new Date(1917, 4, 29));
var bobby = new Person("Robert", "Francis", "Kennedy", new Date(1925, 11, 20));
var teddy = new Person("Edward","Moore","Kennedy", new Date(1932, 1, 22));
// Now, we add those objects to a new Family Tree instance:
var kennedyTree = new FamilyTree();
kennedyTree.addMember(jack);
kennedyTree.addMember(bobby);
kennedyTree.addMember(teddy);
console.log("The tree contains: " + kennedyTree.getMemberCount() + " members.");
console.log(kennedyTree.enumerate());
// Let's remove a member:
kennedyTree.removeMember(bobby);
console.log("The tree contains: " + kennedyTree.getMemberCount() + " members.");
console.log(kennedyTree.enumerate());
I known this has been asked hundreds of times, however, I can't seem to grasp the concept of prototype
Here's my sample script
var config = {
writable: true,
enumerable: true,
configurable: true
};
var defineProperty = function(obj, name, value) {
config.value = value;
Object.defineProperty(obj, name, config);
}
var man= Object.create(null);
defineProperty(man, 'sex', "male");
var person = Object.create(man);
person.greet = function (person) {
return this.name + ': Why, hello there, ' + person + '.'
}
var p=Object.getPrototypeOf(person);
alert(p.sex);//shows male
person.prototype.age=13;//why there is a error said the prototype is undefined? I thought it supposed be man object...
var child=function(){}
child.prototype.color="red";//why this line doesn't show error? both child and person are an object .
alert(child.prototype.color);//shows red
var ch=Object.getPrototypeOf(child);
alert(ch.color);//why it is undefined? it is supposed red.
Hope you can give me some helps... thanks.
Updated:
Thanks your guys kindly help, Based on Elclanrs's answer, Below is what I learned.
Function is the one of the build-in objects in javascript. the 3 format creation function object are equal.
var function_name = new Function(arg1, arg2, ..., argN, function_body)
function function_name(arg1, arg2, ..., argN)
{
...
}
var function_name=function(arg1, arg2, ..., argN)
{
...
}
So, that is why create a prototype chain we have to create a function and then call it with the new keyword .
Function.prototype is the reference to All the Function object prototype.
Cheers
The prototype property only exists on functions, and person is not a function. It's an object.
Here's what's happening:
var man = Object.create(null); // man (object) -> null
man.sex = "male";
var person = Object.create(man); // person (object) -> man (object) -> null
person.greet = function () { ... };
var p = Object.getPrototypeOf(person); // man (object) -> null
alert(p.sex); // p is the same object as man
person.prototype.age = 13; // person doesn't have a prototype
var child = function () {}; // child (function) -> Function.prototype
// -> Object.prototype -> null
child.prototype.color = "red"; // child has a prototype
var ch = Object.getPrototypeOf(child); // Function.prototype
alert(ch.color); // ch is not the same as color.prototype
// ch is Function.prototype
For more information I suggest you read this answer: https://stackoverflow.com/a/8096017/783743
Edit: To explain what's happening in as few words as possible:
Everything in JavaScript is an object except primitive values (booleans, numbers and strings), and null and undefined.
All objects have a property called [[proto]] which is not accessible to the programmer. However most engines make this property accessible as __proto__.
When you create an object like var o = { a: false, b: "something", ... } then o.__proto__ is Object.prototype.
When you create an object like var o = Object.create(something) then o.__proto__ is something.
When you create an object like var o = new f(a, b, ...) then o.__proto__ is f.prototype.
When JavaScript can't find a property on o it searches for the property on o.__proto__ and then o.__proto__.__proto__ etc until it either finds the property or the proto chain ends in null (in which case the property is undefined).
Finally, Object.getPrototypeOf(o) returns o.__proto__ and not o.prototype - __proto__ exists on all objects including functions but prototype only exists on functions.
I think you might be mixing concepts. Try grasping the concept of prototypes with classic prototype inheritance first, then you can get into all the new Object stuff.
In JavaScript, every object (numbers, strings, objects, functions, arrays, regex, dates...) has a prototype which you can think of as a collection of methods (functions) that are common to all current and future instances of that object.
To create a prototype chain you have to create a function and then call it with the new keyword to specify that it is a constructor. You can think of constructors as the main function that takes the parameters necessary to build new instances of your object.
Having this in mind, you can extend native objects or create your own new prototype chains. This is similar to the concept of classes but much more powerful in practice.
Similar to your example, you could write a prototype chain like this:
// Very basic helper to extend prototypes of objects
// I'm attaching this method to the Function prototype
// so it'll be available for every function
Function.prototype.inherits = function(parent) {
this.prototype = Object.create(parent.prototype);
}
// Person constructor
function Person(name, age, sex) {
// Common to all Persons
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype = {
// common to all Persons
say: function(words) {
return this.name +'says: '+ words;
}
};
// Student constructor
function Student(name, age, sex, school) {
// Set the variables on the parent object Person
// using Student as a context.
// This is similar to what other laguanges call 'super'
Person.call(this, name, age, sex);
this.school = school; // unique to Student
}
Student.inherits(Person); // inherit the prototype of Person
var mike = new Student('Mike', 25, 'male', 'Downtown'); // create new student
console.log(mike.say('hello world')); //=> "Mike says: hello world"
In newer version of JavaScript (read EcmaScript) they added new ways to deal with objects and extend them. But the concept it's a bit different from classical prototype inheritance, it seems more complicated, and some more knowledge of how JS works underneath would help to really understand how it works, plus it doesn't work in older browsers. That's why I suggest you start with the classical pattern for which you'll find accurate and abundant information on the internet.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript - this Vs. prototype
Advantages of using prototype, vs defining methods straight in the constructor?
Prototype or inline, what is the difference?
When creating a class in JavaScript, how is declaring methods inside the object using this different then declaring it by accessing the prototype ? it seems to me to serve the same purpose.
window.onload = function() {
tc = new TestClass();
tc.init(); //logs initting
tc.reset(); //logs resetting
tc.doSomething(); //logs doing something
};
var TestClass = function(){
this.init = function(){
console.log("initting");
}
this.reset = function(){
console.log("resetting");
}
this.destroy = function(){
console.log("destroying");
}
}
TestClass.prototype.doSomething = function(){
console.log("doing something");
}
In most situations you will have the same functional result. But internally it's quite different in that when you attach the functions to this, then every instance of the type gets its own copy of the function. By attaching the functions to prototype, all instances share the same function instances. Using prototype reduces memory usage.
Before you read: English is not my mother language ;)
In practice both this and prototype is almost the same, but this and prototype has distinct meaning in javascript.
1) Javascript is based on prototype inheritance. What this mean is that one object can inherit the prototype model from another object. Using prototype you can emulate inheritance on javacript (with limitations), for example:
// create a 'class' Vehicle
var Vehicle = function() {};
Vehicle.prototype.wheels = 0;
Vehicle.prototype.maxSpeed = 0;
Vehicle.prototype.displayInfo = function() {
alert("hello, I have " + this.wheels + " wheels and max speed of " + this.maxSpeed);
};
var vehicleInstance = new Vehicle();
vehicleInstance.displayInfo(); // displays: Hello, I have 0 wheels and max speed of 0
// create a 'class' Car using the prototype from Vehicle
// and change some properties.
var Car = function(maxSpeed) {
if(maxSpeed)
this.maxSpeed = maxSpeed;
};
// inherit the prototype from vehicle
Car.prototype = new Vehicle();
// change some properties
Car.prototype.maxSpeed = 200;
Car.prototype.wheels = 4;
var car = new Car();
car.displayInfo(); // displays: Hello, I have 4 wheels and max speed of 200
2) Properties in this has precedence over properties in prototype, for example:
var car = new Car(); // car prototype: maxSpeed = 200;
car.displayInfo() // displays: Hello, I have 4 wheels and max speed of 200
//set maxSpeed to 300 on 'this'
var car = new Car(300); // see Car definition above
// call displayInfo() in car instance. The Car 'class' doesn't have displayInfo()
// itself, but its prototype has. The javascript VM will look
// for displayInfo() in the car instance, if it not found in the
// instance it will look in car.prototype and on car.prototype.prototype etc.
// until it founds a property called displayInfo()
// or reaches the end of the chain (Object.prototype).
car.displayInfo() // displays: Hello, I have 4 wheels and max speed of 300
This also applies for the prototype of the prototype, for example.
var Class1 = function() { };
Class1.prototype.someValue = 1;
var Class2 = function() { };
Class2.prototype = new Class1();
Class2.prototype.someValue = 2; // this overrides the Class1.prototype.someValue prototype
var class2 = new Class2();
class2.someValue = 3; // this overrides the Class2.prototype.someValue;
3) Properties defined on prototype are not instantiated for every new instance of the same object, for example:
// create a new class and inherit the prototype model from Vehicle.
var Motorcycle = function() { };
Motorcycle.prototype = new Vehicle();
// motorcycles has 2 wheels
Motorcycle.prototype.wheels = 2;
var motorcycle = new Motorcycle();
motorcycle.dysplayInfo(); // displays: Hello, I have 2 wheels and max speed of 200
//now, if I change the method dysplayInfo from Vehicle, it will change for every
//object that inherits Vehicle prototype:
Vehicle.prototype.displayInfo = function() {
Alert("Wheels: " + this.wheels + ", Max speed: " + this.maxSpeed);
}
//observe that I didn't create another Motorcycle instance ,
//I'm using the same instance that I've created before change
//the Vehicle.dysplayInfo() method
motorcycle.displayInfo() // displays: Wheels: 2, Max speed: 200
As you can see, the same method used in Vehicle is used by any object that inherits his prototype. This make your code much more efficient, since you're using the same function for more than one object. You can have thousands of objects inheriting from a fat prototype and still get a low memory footprint.
In short:
By using prototype you are able to create powerful 'classes like' objects, with a well defined inheritance tree (we say prototype chain) which will run more efficiently and will use less memory.
What I have said here does not exhaust the subject of prototype inheritance/chain. Here are other resources you can read. I recommend since understand prototypes in javascript is essencial to write good and maintainable code.
What I have said here does not exhaust the subject of prototypes:
https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript?redirectlocale=en-US&redirectslug=Introduction_to_Object-Oriented_JavaScript
http://javascript.crockford.com/prototypal.html
http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
They have the same effect in that particular case, but they're very different. One (the?) major difference is that methods attached using this are properties of the object itself and not of its prototype, so iterating the object like so:
for(var x in tc) {
if(tc.hasOwnProperty(x)) {
console.log('Has property ' + x);
}
}
will omit methods added using prototype. Another difference is the references; assigning the methods to this will create new function objects each time, but using the prototype, they're all the same function. (This may or may not be what you want, and it matters most when attaching extra properties to the methods.)