Javascript - OOP

javascript
OOP 2

http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/
http://manuel.kiessling.net/2012/03/23/object-orientation-and-inheritance-in-javascript-a-comprehensive-explanation/

Articles
Prototypal
Classical

var Person = function(name, age){
  this.name = name;
  this.age = age;
}

Now let’s add a method onto our Person’s prototype so it will be available on every instance of our Person ‘class’.

Person.prototype.sayName = function(){
  alert(‘My name is ‘ + this.name);
}

Now, because we put the sayName function on the prototype, every instance of Person will be able to call the sayName function in order alert that instance’s name.

Now that we have our Person constructor function and our sayName function on its prototype, let’s actually create an instance of Person then call the sayName function.

var tyler = new Person(‘Tyler’, 23);
tyler.sayName(); //alerts ‘My name is Tyler’

Now let’s look at what actually is happening when you use the ‘new’ keyword in JavaScript. First thing you should notice is that after using ‘new’ in our example, we’re able to call a method (sayName) on ‘tyler’ just as if it were an object - that’s because it is. So first, we know that our Person constructor is returning an object, whether we can see that in the code or not. Second, we know that because our sayName function is located on the prototype and not directly on the Person instance, the object that the Person function is returning must be delegating to its prototype on failed lookups. In more simple terms, when we call tyler.sayName() the interpreter says “OK, I’m going to look on the ‘tyler’ object we just created, locate the sayName function, then call it. Wait a minute, I don’t see it here - all I see is name and age, let me check the prototype. Yup, looks like it’s on the prototype, let me call it.”.

Object.create = Object.create || function(o) {
  var F = function () {};
  F.prototype = o;
  return new F();
}
// JavaScript - OOP

// JavaScript - Prototypal Inheritance:

JavaScript does not follow the classical OOP.  JavaScript OOP is based on
prototypal inheritance.

In JavaScript, each object internally references another object, called its 
prototype. That prototype object, in turn, has a reference to its prototype 
object, and so on. At the end of this prototype chain is an object with null as 
its prototype. The prototype chain is the mechanism by which prototypal 
inheritance is achieved in JavaScript. In particular, when a reference is made 
to a property that an object does not itself contain, the prototype chain is 
traversed until the referenced property is found (or until the end of the chain 
is reached, in which case the property is undefined).

When we make change to an object, the object's prototype is not touched.  The
prototype link is used only in retrieval.  If we try to retrieve a property 
value from an object, and if the object does not have that property name, then
JavaScript attempts to retrieve value from the prototype object.  And if that
object does not have the property, then its goes to its prototype, and so on
until it finally bottoms out with Object.prototype.  If the desired property
exists nowhere in the prototype chain, then the result is the undefined value.
This is called delegation.

The prototype relationship is a dynamic relationship.  If we add a new property
to a prototype, that property will immediately be visible in all objects that
are based on that prototype.

function Animal() { 
  this.eatsVeggies = true; 
  this.eatsMeat = false; 
}

function Herbivore() {}
Herbivore.prototype = new Animal();

function Carnivore() { 
  this.eatsMeat = true; 
}
Carnivore.prototype = new Animal();

var rabbit = new Herbivore();
var bear = new Carnivore();

console.log(rabbit.eatsMeat);   // logs "false"
console.log(bear.eatsMeat);     // logs "true"

// JavaScript - Class Augmentation:

JavaScript's dynamism allows us to add or replace methods of an existing class. 
We can call the method method at any time, and all present and future instances 
of the class will have that method. We can literally extend a class at any time.  
We call this Class Augmentation  to avoid confusion with Java's extends, which 
means something else.

// JavaScript - Object Augmentation:

In the static object-oriented languages, if you want an object which is 
slightly different than another object, you need to define a new class. In 
JavaScript, you can add methods to individual objects without the need for 
additional classes. This has enormous power because you can write far fewer 
classes and the classes you do write can be much simpler. Recall that JavaScript 
objects are like hashtables. You can add new values at any time. If the value is 
a function, then it becomes a method.

// JavaScript - Parasitic Inheritance:

There is another way to write ZParenizor. Instead of inheriting from Parenizor, 
we write a constructor that calls the Parenizor constructor, passing off the 
result as its own. And instead of adding public methods, the constructor adds 
privileged methods:

function ZParenizor2(value) {
    var that = new Parenizor(value);
    that.toString = function () {
        if (this.getValue()) {
            return this.uber('toString');
        }
        return "-0-"
    };
    return that;
}

Classical inheritance is about the is-a relationship, and parasitic inheritance 
is about the was-a-but-now's-a relationship. The constructor has a larger role 
in the construction of the object. Notice that the uber  née super method is 
still available to the privileged methods.

// Drawback of creating true private methods in JavaScript:

One of the drawbacks of creating true private methods in JavaScript is that 
they are very memory-inefficient, as a new copy of the method would be created 
for each instance.

var Employee = function (name, company, salary) {
    this.name = name || "";       //Public attribute default value is null
    this.company = company || ""; //Public attribute default value is null
    this.salary = salary || 5000; //Public attribute default value is null

    // Private method
    var increaseSalary = function () {
        this.salary = this.salary + 1000;
    };

    // Public method
    this.dispalyIncreasedSalary = function() {
        increaseSlary();
        console.log(this.salary);
    };
};
var emp1 = new Employee("John","Pluto",3000);
var emp2 = new Employee("Merry","Pluto",2000);
var emp3 = new Employee("Ren","Pluto",2500);

Here each instance variable emp1, emp2, emp3 has its own copy of the 
increaseSalary private method.  So, don’t use private methods unless 
it’s necessary.

Does JavaScript use classical inheritance by default?

No. JavaScript is a class-free, object-oriented language. By default, tt uses prototypal inheritance instead of classical inheritance.

What is Class Augmentation?

JavaScript's dynamism allows us to add or replace methods of an existing class. We can call the method method at any time, and all present and future instances of the class will have that method. We can literally extend a class at any time. We call this Class Augmentation to avoid confusion with Java's extends, which means something else.

What is Object Augmentation?

In the static object-oriented languages, if you want an object which is slightly different than another object, you need to define a new class. In JavaScript, you can add methods to individual objects without the need for additional classes. This has enormous power because you can write far fewer classes and the classes you do write can be much simpler. Recall that JavaScript objects are like hashtables. You can add new values at any time. If the value is a function, then it becomes a method.

What is Parasitic Inheritance?

There is another way to write ZParenizor. Instead of inheriting from Parenizor, we write a constructor that calls the Parenizor constructor, passing off the result as its own. And instead of adding public methods, the constructor adds privileged methods:

function ZParenizor2(value) {
    var that = new Parenizor(value);
    that.toString = function () {
        if (this.getValue()) {
            return this.uber('toString');
        }
        return "-0-"
    };
    return that;
}

Classical inheritance is about the is-a relationship, and parasitic inheritance is about the was-a-but-now's-a relationship. The constructor has a larger role in the construction of the object. Notice that the uber née super method is still available to the privileged methods.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License