Can we assign a public method inside a object constructor ? (javascript) - javascript

I am reading about prototypes in javascript, In a article http://phrogz.net/js/classes/OOPinJS.html I read that we can not assign public methods inside a object constructor in javascript ? How prototypal methods are different from static methods and what are the advantage of using them ?

I read that we can not assign public methods inside a object constructor in javascript?
Yes, the article refers to this:
function MyObj(name)
{
this.name = name;
}
MyObj.prototype.sayHello = function() {
alert('hello ' + this.name);
}
new MyObj('world').sayHello();
As you can see, the public method sayHello() is declared in the prototype, which is done outside of the constructor. This is just how JavaScript works.
How prototypal methods are different from static methods and what are the advantage of using them ?
Prototypal methods are only "attached" to objects. For static methods you need to use this construct:
var MyStaticThing = {
name: 'world',
sayHello: function() {
alert('hello ' + this.name);
}
}
MyStaticThing.sayHello();

JavaScript isn't really well suited for most OOP concepts and paradigms, especially once you try to emulate inheritance. Rather than think of prototype vs "privileged" methods in OOP terms, you should think of things in terms of how JavaScript instantiates objects. Take this simple "class":
var id = 0;
function myClass()
{
var that = this;
id++; //closure, each new instance gets a unique id
this.id = id;
this.toString = function()
{
return that.id.toString();
}
}
And this class is instantiated like so:
var classInstance = new myClass();
This isn't a pattern I would necessarily recommend, the point is to illustrate that for each instantiation, each instance gets its own unique toString function. That means if you instantiate 100 classInstances, and you change toString on one of them to do something else, only that one instance will have that new functionality.
That also means that for every instance, every privileged method is also instantiated alongside with it. If you are instantiating a lot of instances, that can make a big performance difference. I had a case where I saw a measurable speed improvement by converting my privileged methods to prototype methods.
Speaking of prototype methods, here's what that might look like:
var id = 0;
function myClass()
{
id++; //closure, each new instance gets a unique id
this.id = id;
}
myClass.prototype.toString = function()
{
return this.id.toString();
}
In this case no matter how many myClasses you have, you only instantiate the toString method once. And if it changes, it changes for all myClasses.
Personally, I use privileged methods in most of my JavaScript classes because it looks cleaner and only bother with the prototype chain if I know it's going to be instantiated a huge number of times. Also being able to access private variables allows you to have some semblance of information hiding vs being forced to make any accessed variables public.

"the advantage of using them"...which one are you referring? Generally the advantage is going to be using a prototypal method (and object construction generally), over something like static or classical methods in javascript. The answer you are looking for is really too long to address here, but the short answer is that javascript is based off a prototypal object inheritance system (meaning objects can be created on the fly and may inherited one to the other), as opposed to a classical system (objects may only inherit from classes, i.e. Java, C++, etc.)
While you may create objects in javascript in a classical way -- because the language is that flexible -- it is a bad and confused way to do it. Prototypical object construction allows you do important and good things like data hiding, access to super methods, etc. Like I said this is a verbose subject, really to big to be taken on in a little text box.

Related

Usecase for JavaScript prototype [duplicate]

I'd like to understand when it is appropriate to use prototype methods in js. Should they always be used? Or are there cases where using them is not preferred and/or incurs a performance penalty?
In searching around this site on common methods for namespacing in js, it seems that most use a non-prototype based implementation: simply using an object or a function object to encapsulate a namespace.
Coming from a class-based language, it's hard not to try and draw parallels and think that prototypes are like "classes" and the namespace implementations I mentioned are like static methods.
Prototypes are an optimisation.
A great example of using them well is the jQuery library. Every time you obtain a jQuery object by using $('.someClass'), that object has dozens of "methods". The library could achieve that by returning an object:
return {
show: function() { ... },
hide: function() { ... },
css: function() { ... },
animate: function() { ... },
// etc...
};
But that would mean that every jQuery object in memory would have dozens of named slots containing the same methods, over and over.
Instead, those methods are defined on a prototype and all jQuery objects "inherit" that prototype so as to gain all those methods at very little runtime cost.
One vitally important part of how jQuery gets it right is that this is hidden from the programmer. It's treated purely an optimisation, not as something that you have to worry about when using the library.
The problem with JavaScript is that naked constructor functions require the caller to remember to prefix them with new or otherwise they typically don't work. There is no good reason for this. jQuery gets it right by hiding that nonsense behind an ordinary function, $, so you don't have to care how the objects are implemented.
So that you can conveniently create an object with a specified prototype, ECMAScript 5 includes a standard function Object.create. A greatly simplified version of it would look like this:
Object.create = function(prototype) {
var Type = function () {};
Type.prototype = prototype;
return new Type();
};
It just takes care of the pain of writing a constructor function and then calling it with new.
When would you avoid prototypes?
A useful comparison is with popular OO languages such as Java and C#. These support two kinds of inheritance:
interface inheritance, where you implement an interface such that the class provides its own unique implementation for every member of the interface.
implementation inheritance, where you extend a class that provides default implementations of some methods.
In JavaScript, prototypical inheritance is a kind of implementation inheritance. So in those situations where (in C# or Java) you would have derived from a base class to gain default behaviour, which you then make small modifications to via overrides, then in JavaScript, prototypical inheritance makes sense.
However, if you're in a situation where you would have used interfaces in C# or Java, then you don't need any particular language feature in JavaScript. There is no need to explicitly declare something that represents the interface, and no need to mark objects as "implementing" that interface:
var duck = {
quack: function() { ... }
};
duck.quack(); // we're satisfied it's a duck!
In other words, if each "type" of object has its own definitions of the "methods", then there is no value in inheriting from a prototype. After that, it depends on how many instances you allocate of each type. But in many modular designs, there is only one instance of a given type.
And in fact, it has been suggested by many people that implementation inheritance is evil. That is, if there are some common operations for a type, then maybe it's clearer if they are not put into a base/super class, but are instead just exposed as ordinary functions in some module, to which you pass the object(s) you want them to operate on.
You should use prototypes if you wish to declare a "non-static" method of the object.
var myObject = function () {
};
myObject.prototype.getA = function (){
alert("A");
};
myObject.getB = function (){
alert("B");
};
myObject.getB(); // This works fine
myObject.getA(); // Error!
var myPrototypeCopy = new myObject();
myPrototypeCopy.getA(); // This works, too.
One reason to use the built-in prototype object is if you'll be duplicating an object multiple times that will share common functionality. By attaching methods to the prototype, you can save on duplicating methods being created per each new instance. But when you attach a method to the prototype, all instances will have access to those methods.
Say you have a base Car() class/object.
function Car() {
// do some car stuff
}
then you create multiple Car() instances.
var volvo = new Car(),
saab = new Car();
Now, you know each car will need to drive, turn on, etc. Instead of attaching a method directly to the Car() class (which takes up memory per each instance created), you can attach the methods to the prototype instead (creating the methods only once), therefore giving access to those methods to both the new volvo and saab.
// just mapping for less typing
Car.fn = Car.prototype;
Car.fn.drive = function () {
console.log("they see me rollin'");
};
Car.fn.honk = function () {
console.log("HONK!!!");
}
volvo.honk();
// => HONK!!!
saab.drive();
// => they see me rollin'
Put functions on a prototype object when you're going to create lots of copies of a particular kind of object and they all need to share common behaviors. By doing so, you'll save some memory by having just one copy of each function, but that's only the simplest benefit.
Changing methods on prototype objects, or adding methods, instantly changes the nature of all the instances of the corresponding type(s).
Now exactly why you'd do all these things is mostly a function of your own application design, and the kinds of things you need to do in client-side code. (A whole different story would be code inside a server; much easier to imagine doing more large-scale "OO" code there.)
If i explain in class based term then Person is class, walk() is Prototype method. So walk() will have its existence only after you instantiate new object with this.
So if you want to create the copies of object like Person u can create many users Prototype is good solution as it saves memory by sharing/inheriting same copy of function for each of the object in memory.
Whereas static is not that great help in such scenario.
function Person(){
this.name = "anonymous";
}
// its instance method and can access objects data data
Person.prototype.walk = function(){
alert("person has started walking.");
}
// its like static method
Person.ProcessPerson = function(Person p){
alert("Persons name is = " + p.name);
}
var userOne = new Person();
var userTwo = new Person();
//Call instance methods
userOne.walk();
//Call static methods
Person.ProcessPerson(userTwo);
So with this its more like instance method.
The object's approach is like Static methods.
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
Just including a video link here for reference, when not to use prototypes: https://youtu.be/JCXZhe6KsxQ?t=2m30s
Here is Ben Lesh's talk from NGConf, why rxjs removed patching prototype (chainable functions) in favor of pipeable functions.

If Javascript's native OOP is classless, what about the constructor? Doesn't that imply a class?

I think Javascript native OOP system is said to be classless, and is object-based, not class-based. But every example I see always start with a constructor similar to
function Person(name) {
this.name = name;
}
Just by using a constructor this way, doesn't this already imply a class is being used? (a class called Person)
Details:
If we can use
a.__proto__ = b;
on any Javascript platform, then I think it is classless. But we can't do that. If we want that behavior, we need to use
function F() { }
F.prototype = b;
a = new F();
and so, a constructor has to be used. So if constructor is such a cornerstone in Javascript, that means it is intended to be constructor of Person, Widget, etc, and these are classes.
The OOP in Javascript is slightly different from, for instance, the Java OOP.
The Javascript constructors do not refer to a class definition (so it is classless). Rather the constructor refers to a prototype. The base of the OOP in Javascript is the Object object (not the Object class), from where all the others objects are derived.
Prototyping grants you inheritance, and the possibility to extend an existing object with properties and methods.
I suggest you this article.
In your example:
function Person(name) {
this.name = name;
}
Mike = new Person('Mike');
the Person() function lets you create a new object prototyped on the Object object with a new property called name. Well, such a kind of function in Javascript oop is called a constructor.
Classless may be an inaccurate way to describe JavaScript's approach on OOP.
JavaScript does lack class definitions.
It also lacks a class-to-object correspondence.
You can't check if an object instantiated with a constructor such as Person is of class Person.
You can check if it contains the expected object members and conclude that it is of the expected class.
But if the object members have been changed along the way you're not going to get the desired/expected result.
TL;DR
JavaScript exposes constructors (appropriately named prototypes) as a manner in which you can define a template for constructing plain objects.
The important thing is that the end result of a prototype call is a plain object with some predefined members and not an object of a certain class .
It's good to think of javascript as a classless environment. If you think javascript classes you should be able to assume there's certain useful things you can do when there are classes and they're strictly enforced. However those certain useful things you cannot assume. The presence of something that looks like a constructor does not indicate you're creating a class.
For example, let's say you var dude = Person('Ashton Kutcher'). Now, when you dude instanceOf person, you get true. You assume you have the properties and methods of a person. What if some code comes along and says dude.personMethod = undefined. Now, while dude instanceOf person will still be true, the personMethod is no longer available.
You can think of javascript as having classes but it's a leaky abstraction. It's better to think of javascript as having a prototypal inheritance system when it comes to determining what something is and what you can expect of it.
More information here: http://javascript.crockford.com/prototypal.html
Create a class using the Object Constructor and prototyping can help us
in creating many instances of the class without redefining the object each time wee need it.
so in the above example
function Person(name)
{
this.name = name;
}
you can create two persons with different names.
example :
var personA = new Person();
personA.name = "james";
var personB = new Person();
personB.name = "Tom";
alert(personA.name + personB.name);
i suggest you reading this link will be helpful
http://www.javascriptkit.com/javatutors/oopjs2.shtml

Javascript when to use prototypes

I'd like to understand when it is appropriate to use prototype methods in js. Should they always be used? Or are there cases where using them is not preferred and/or incurs a performance penalty?
In searching around this site on common methods for namespacing in js, it seems that most use a non-prototype based implementation: simply using an object or a function object to encapsulate a namespace.
Coming from a class-based language, it's hard not to try and draw parallels and think that prototypes are like "classes" and the namespace implementations I mentioned are like static methods.
Prototypes are an optimisation.
A great example of using them well is the jQuery library. Every time you obtain a jQuery object by using $('.someClass'), that object has dozens of "methods". The library could achieve that by returning an object:
return {
show: function() { ... },
hide: function() { ... },
css: function() { ... },
animate: function() { ... },
// etc...
};
But that would mean that every jQuery object in memory would have dozens of named slots containing the same methods, over and over.
Instead, those methods are defined on a prototype and all jQuery objects "inherit" that prototype so as to gain all those methods at very little runtime cost.
One vitally important part of how jQuery gets it right is that this is hidden from the programmer. It's treated purely an optimisation, not as something that you have to worry about when using the library.
The problem with JavaScript is that naked constructor functions require the caller to remember to prefix them with new or otherwise they typically don't work. There is no good reason for this. jQuery gets it right by hiding that nonsense behind an ordinary function, $, so you don't have to care how the objects are implemented.
So that you can conveniently create an object with a specified prototype, ECMAScript 5 includes a standard function Object.create. A greatly simplified version of it would look like this:
Object.create = function(prototype) {
var Type = function () {};
Type.prototype = prototype;
return new Type();
};
It just takes care of the pain of writing a constructor function and then calling it with new.
When would you avoid prototypes?
A useful comparison is with popular OO languages such as Java and C#. These support two kinds of inheritance:
interface inheritance, where you implement an interface such that the class provides its own unique implementation for every member of the interface.
implementation inheritance, where you extend a class that provides default implementations of some methods.
In JavaScript, prototypical inheritance is a kind of implementation inheritance. So in those situations where (in C# or Java) you would have derived from a base class to gain default behaviour, which you then make small modifications to via overrides, then in JavaScript, prototypical inheritance makes sense.
However, if you're in a situation where you would have used interfaces in C# or Java, then you don't need any particular language feature in JavaScript. There is no need to explicitly declare something that represents the interface, and no need to mark objects as "implementing" that interface:
var duck = {
quack: function() { ... }
};
duck.quack(); // we're satisfied it's a duck!
In other words, if each "type" of object has its own definitions of the "methods", then there is no value in inheriting from a prototype. After that, it depends on how many instances you allocate of each type. But in many modular designs, there is only one instance of a given type.
And in fact, it has been suggested by many people that implementation inheritance is evil. That is, if there are some common operations for a type, then maybe it's clearer if they are not put into a base/super class, but are instead just exposed as ordinary functions in some module, to which you pass the object(s) you want them to operate on.
You should use prototypes if you wish to declare a "non-static" method of the object.
var myObject = function () {
};
myObject.prototype.getA = function (){
alert("A");
};
myObject.getB = function (){
alert("B");
};
myObject.getB(); // This works fine
myObject.getA(); // Error!
var myPrototypeCopy = new myObject();
myPrototypeCopy.getA(); // This works, too.
One reason to use the built-in prototype object is if you'll be duplicating an object multiple times that will share common functionality. By attaching methods to the prototype, you can save on duplicating methods being created per each new instance. But when you attach a method to the prototype, all instances will have access to those methods.
Say you have a base Car() class/object.
function Car() {
// do some car stuff
}
then you create multiple Car() instances.
var volvo = new Car(),
saab = new Car();
Now, you know each car will need to drive, turn on, etc. Instead of attaching a method directly to the Car() class (which takes up memory per each instance created), you can attach the methods to the prototype instead (creating the methods only once), therefore giving access to those methods to both the new volvo and saab.
// just mapping for less typing
Car.fn = Car.prototype;
Car.fn.drive = function () {
console.log("they see me rollin'");
};
Car.fn.honk = function () {
console.log("HONK!!!");
}
volvo.honk();
// => HONK!!!
saab.drive();
// => they see me rollin'
Put functions on a prototype object when you're going to create lots of copies of a particular kind of object and they all need to share common behaviors. By doing so, you'll save some memory by having just one copy of each function, but that's only the simplest benefit.
Changing methods on prototype objects, or adding methods, instantly changes the nature of all the instances of the corresponding type(s).
Now exactly why you'd do all these things is mostly a function of your own application design, and the kinds of things you need to do in client-side code. (A whole different story would be code inside a server; much easier to imagine doing more large-scale "OO" code there.)
If i explain in class based term then Person is class, walk() is Prototype method. So walk() will have its existence only after you instantiate new object with this.
So if you want to create the copies of object like Person u can create many users Prototype is good solution as it saves memory by sharing/inheriting same copy of function for each of the object in memory.
Whereas static is not that great help in such scenario.
function Person(){
this.name = "anonymous";
}
// its instance method and can access objects data data
Person.prototype.walk = function(){
alert("person has started walking.");
}
// its like static method
Person.ProcessPerson = function(Person p){
alert("Persons name is = " + p.name);
}
var userOne = new Person();
var userTwo = new Person();
//Call instance methods
userOne.walk();
//Call static methods
Person.ProcessPerson(userTwo);
So with this its more like instance method.
The object's approach is like Static methods.
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
Just including a video link here for reference, when not to use prototypes: https://youtu.be/JCXZhe6KsxQ?t=2m30s
Here is Ben Lesh's talk from NGConf, why rxjs removed patching prototype (chainable functions) in favor of pipeable functions.

javascript inheritance

I know there is a lot of similar questions are tons of great answers to this. I tried to look at the classical inheritance methods, or those closure methods etc. Somehow I consider they are more or less "hack" methods to me, as it doesn't really what the javascript is designed to do. (Welcome anybody correct me if I am wrong).
OK, as long as it works, I satisfy with the classical inheritance pattern like:
PARENTClass = function (basevar) { do something here; };
PARENTClass.prototype = { a: b, c: d}; // prototype is auto gen
// Inheritance goes here
CHILDClass = function (childvar) { do something; };
CHILDClass.prototype = new PARENTClass(*1); // Actual inheritance to the prototype statement
// Instance
CHILDInstance = new CHILDClass(whatever);
Above is somehow, to my understanding the inheritance of JS. But one scenario I have no idea how to implement, is that what if I want to do some initializing DURING object creation (ie, within constructor), and the new object can be used right away.... My illustration on problem might not be too clear, so let me use the following C# Psuedo to explain what I want to do:
class PARENT {
public PARENT (basevar) { ... }
}
class CHILD : PARENT {
public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
{ ... }
}
For some reason (like init. UI elements), putting them in constructor seems the best way to do. Anyone have idea on how can I do it.
PS: in the *1, I have no idea what I should put there.
PS2: The above situation I DID found the jquery.inherit library can do, I just wonder if not using library can achieve it.
PS3: Or my understanding is wrong. Since javascript is not intended to mimick OOP (that's why i call it hack), what is the "CORRECT" logic to implement this.
It is not a hack as such; JavaScript is a prototyped language, as defined by Wikipedia as where:
..classes are not present, and behavior reuse (known as inheritance in class-based languages) is performed via a process of cloning existing objects that serve as prototypes.
As it says, classes are not used in JavaScript; each object that you create is descended from the JavaScript Object; all objects in JavaScript have the prototype object, and all instances of objects you create 'inherit' methods and properties from their object's prototype object. Take a look at the MDC prototype object reference for more information.
As of this, when you call the line:
CHILDClass.prototype = new PARENTClass();
This allows the CHILDClass object to add methods and properties to its prototype object from the PARENTClass object, which creates an effect similar to the idea of inheritance present in class-based languages. Since the prototype object affects every instance created of that object, this allows the parent object's methods and properties to be present in every instance of your child object.
If you want to call your parent class's constructor in your child class's constructor, you use the JavaScript call function; this allows you to call the parent class's constructor in the context of the child class's constructor, therefore setting the newly prototyped properties in your child class to what they are set as in the parent class.
You also do not need to put anything where you have specified the *1, since that line is merely used to add the methods and properties to the child class's prototype object; however, bear in mind that it calls the parent class's constructor, so if there are any arguments that are fundamental in the operation of the parent class constructor, you should check that these are present so as to avoid JavaScript errors.
You can manually invoke the parent constructor in the subclass constructor like this:
CHILDClass = function (basevar) {
PARENTClass.call(this, basevar);
// do something;
};
The trick here is using the call method, which allows you to invoke a method in the context of a different object. See the documentation of call for more details.
JavaScript has no built-in support for inheritance hierarchies as type extension is supposed to be done via aggregation, ie adding desired functionality directly to the object itself or its prototype if the property is to be shared between instances.
Nevertheless, JS is powerful enough to make implementing other forms of object construction possible, including classical inheritance.
Given a clone function - which is enough to add 'true' prototypical inheritance, and not JavaScript's bastardization thereof - your exampe can be implemented like this:
function ParentClass(baseVar) {
// do stuff
}
// don't overwrite the prototype object if you want to keep `constructor`
// see http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
ParentClass.prototype.a = 'b';
ParentClass.prototype.c = 'd';
function ChildClass(childVar) {
// call the super constructor
ParentClass.call(this, childVar);
}
// don't inherit from a ParentClass instance, but the actual prototype
ChildClass.prototype = clone(ParentClass.prototype);
ChildClass.prototype.e = 'f';
It's also possible to add some syntactic sugar for class-based inheritance - my own implementation can be found here.
The example from above would then read
var ParentClass = Class.extend({
constructor: function(baseVar) {
// do stuff
},
a: 'b',
c: 'd'
});
var ChildClass = ParentClass.extend({
e: 'f'
});
I've got a lightweight javascript OOP wrapper that provides 'Class-like' inheritance where you can override base methods or call base constructors or members.
You define your classes like this:
//Define the 'Cat' class
function Cat(catType, firstName, lastName)
{
//Call the 'Animal' constructor.
Cat.$baseNew.call(this, firstName, lastName);
this.catType = catType;
}
//Extend Animal, and Register the 'Cat' type.
Cat.extend(Animal, { type: 'Cat' }, {
hello: function(text)
{
return "meaoow: " + text;
},
getFullName: function()
{
//Call the base 'Animal' getFullName method.
return this.catType + ": " + Cat.$base.getFullName.call(this);
}
})
//It has a built-in type system that lets you do stuff like:
var cat = new Cat("ginger", "kitty", "kat");
Cat.getType() // "Cat"
cat.getBaseTypesAndSelf() // ["Cat","Animal","Class"]
cat.getType() // "Cat"
cat.isTypeOf(Animal.getType()) // "True"
var dynamicCat = Class.createNew("Cat", ["tab","fat","cat"])
dynamicCat.getBaseTypesAndSelf() // ["Cat","Animal","Class"]
dynamicCat.getFullName() // tab: fat cat
source code available at: Class.js
I also have more details in my blog post about OOP in javascript
Just thought I'd mention some of the issues with the classical pattern you're going for:
Reference vars on the super class(es) will be available as essentially statics on ALL instances. For example, if you have var arr = [1,2,3] in the super, and do instance_1.arr.push(4) instance_2.arr.push(5) ALL of these instances will "see" the changes.
So you solve 1. with Ayman's solution which Zakas calls "Constructor Stealing", but now you call the constructor twice: once for your prototype and once for the constructor stealing. Solution - for your prototype use a helper like inheritPrototype (I showed the whole implementation of this in this post: inheritPrototype method FWIW, this essentially came from a combination of page 181 of Zakas's book and some Crockford study.
No privacy (but then again, you'd need to use something like the Durable Object pattern to get this and that may not be what you want)
Object definition is left "dangling": Solution - put an if statement checking for any of your prototype's functions and then define the prototype with a prototype literal.
I have running examples of all of this on github!!!
It's been just as much of a challenge for me to truly grok both: Zakas and Crockford books on object creation and inheritance. I also needed to try some different JavaScript TDD frameworks. So I decided to create an essay on both TDD Frameworks and JavaScript Object Creation & Inheritance. It has running code and jspec tests! Here's the link:*
My GitHub Open Source Essay/Book

borrowing costructors and prototype chain

in many books and online tutorial there are examples on passing data to a super-class
constructor via a borrowing method pattern:
var Parent = function(name)
{
this.name = name;
this.my_parent = "parent_property";
this.go = function()
{
alert("GO")
}
}
var Child = function(name)
{
this.name = name;
this.my_child = "child_property";
Parent.call(this);
alert(this.hasOwnProperty("go")) // HERE TRUE!!!
}
var ChildChild = function(name)
{
this.name = name;
this.su = function(){}
}
// PSEUDO CLASSICAL ECMA STANDARD
Child.prototype = new Parent("PARENT");
ChildChild.prototype = new Child("CHILD");
var c = new ChildChild("CHILDCHILD");
now my question is: is this correct? in that pattern the properties of the super-class
are copied into THIS but in a OOP system I think that those properties must be in its
super-class. Now BORROWING constructor is only another pattern to make a sort of inheritance so I could not use prototype and so all the chain superclass properties are
into the last child class...but I don't think it's efficient.
So, at end, how can I pass data to a super-class without that pattern?
Thanks
By calling .call() you don't inherit in the classical sense of the word instead you tell Child to apply Parents prototype onto itself and thus Child.prototype has cloned properties and methods from Parent. This has no issues performance wise whatsoever though so abandoning prototype for efficiency reasons is not a valid reason.
If I can be honest I think enforcing OO paradigms onto javascript is the biggest mistake a javascript developer can make. Much like having to learn to deal with immutability in functional programming trying to make javascript behave like classical OO will only work against you in the long run.
It doesn't answer your question but there's tons of different ways to apply a super functionality to javascript none of which I can recommend though as there's no definitive version that doesn't come with a downside somewhere down the line.
JavaScript has no inherent support for building inheritance hierachies. The JavaScript way of doing type extensions would be to add properties from the 'parent class' to the 'child class', ie
function Parent(foo) {
this.foo = foo;
}
Parent.prototype.sharedFoo = 'sharedFoo';
function Child(foo, bar) {
// call the parent constructor
Parent.call(this, foo);
this.bar = bar;
}
Child.prototype.sharedBar = 'sharedBar';
// copy the properties of the parent class
for(var prop in Parent.prototype) {
if(Parent.prototype.hasOwnProperty(prop))
Child.prototype[prop] = Parent.prototype[prop];
}
It's also easily possible to add true prototypical inheritance, for example like this.
Via use of the clone() function, it's now possible to let the prototype object of the 'child class' inherit from the prototype object of the 'base class':
function Parent(foo) {
this.foo = foo;
}
Parent.prototype.sharedFoo = 'sharedFoo';
function Child(foo, bar) {
// call the parent constructor
Parent.call(this, foo);
this.bar = bar;
}
// inherit from the parent class
Child.prototype = clone(Parent.prototype);
Child.prototype.sharedBar = 'sharedBar';
JavaScript is a prototype based, functional language that pretends to be the cousin of Java.
Here is a few key things about JavasSript:
Everything is an Object, including Functions
Object is more like Hash, it is a collection of key value pairs
prototype itself is Object as well
To answer your first question about performance of "borrowing" prototype:
Typically, a JavaScript class contains a collection of [name, function object] pairs. When you borrow the prototype of the parent class, you basically copy the values of the parent prototype object into child class's prototype object.
The copy is by reference, when the function is copied, the function code is not duplicated, only the reference is copied. This is similar to function pointers in C language.
Thus the only performance hit is the
duplication of the prototype object,
which takes very little memory.
To answer your second question of how to pass data to Parent Class in a clean way:
There are many libraries out there that has some OOP style inheritance already built in. You can roll your own as well, but that would not be trivial.
I recommend a framework called Joose.
It supports classes, inheritance, mixins, traits, method modifiers and more.
Stable and used in production environments.
Elegant, and will save you a lot of key strokes
Using Joose, parent constructors can be overridden
or augmented, and SUPER() or INNER()
methods will be provided to access the
original constructor, or the subclass
constructor.

Categories

Resources