as a developer with OOP background(c#, Java) OOP JavaScript is wild horse for me. I am trying learn nuts and bolts of language and then jump on libraries (Am I wrong?);
so, I checked dozen of books/tutorials about objects, functions...etc..learned several ways to create objects but syntax used in almost every JS library confuses me. namely
var Person = Backbone.extend.Model({
//pretty complex staff
})
what is Model behind the scenes? object? function?
That is not the correct backbone syntax. That should actually be:
Backbone.Model.extend({
});
In that case, extend is a function. Note that you are invoking it with (). However, functions in javascript are also objects (more on that in a moment). You may be confused about the {} inside of it. That is because you are passing that object as a parameter to the function.
If extend was a function that expected a string as a parameter/argument, it would look like this: extend('some string'). In this case, it is taking an object. For example:
var someObject = {
someProperty: 'someValue'
}
var Person = Backbone.Model.extend(someObject);
is the same as:
var Person = Backbone.Model.extend({
someProperty: 'someValue'
});
Here's just a sample of how that might look in the function:
Backbone.Model.extend = function(obj) {
console.log(obj.someProperty); //logs "someValue"
}
As I said, in javascript, functions are also objects. Actually, most things are objects. I recommend you study more on this. As it's not the focus of your question, I'll just briefly demonstrate:
var someObj = {
someProperty: '123'
};
console.log(someObj.someProperty); //logs "123"
var someFunction = function() {
};
someFunction.someProperty = '123';
console.log(someFunction.someProperty); //logs "123"
Though, it would be better to add to the prototype so that inheritance will work like this:
someFunction.prototype.someProperty = '123';
var foo = new someFunction();
console.log(foo.someProperty); //logs "123"
Here's a little demo you can mess with (click).
So.. in summary, JavaScript is win-sauce.
Are you sure you typed this in correctly? I think you reversed the order of Model and extend. I'm looking at the documentation now, and I see:
Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes.
The extend function is implemented in many Javascript libraries: Backbone, Underscore, and jQuery for a few. What it does is to take an object and add methods and instance variables to it. After all in Javascript, objects are simply hashes. This creates an object that has a few methods and data.
var counter = {};
counter.count = 0;
counter.increment = function() {
this.count++;
}
counter.decrement = function() {
this.count--;
}
If you want inheritance, you use the object or its constructor's prototype property. The extend method is a way of simulating that. Here's more of the Backbone documentation:
extendBackbone.Model.extend(properties, [classProperties])
To create a Model class of your own, you extend Backbone.Model and provide instance properties, as well as optional classProperties to be attached directly to the constructor function.
extend correctly sets up the prototype chain, so subclasses created with extend can be further extended and subclassed as far as you like.
var Note = Backbone.Model.extend({
initialize: function() { ... },
author: function() { ... },
coordinates: function() { ... },
allowedToEdit: function(account) {
return true;
}
});
In conventional Javascript, you'd write:
function Note() {
this.initialize = function() {...};
this.author = function() {...};
this.coordinates = function() {...};
this.allowedToEdit = function(account) {
return true;
};
}
Note.prototype = new Model(); // Inheritance.
Inheritance in JavaScript reminds me of the Perl maxim: There's More than One Way to Do This.
Welcome to stackoverflow,
I strongly advise you to have a look at Douglas Crockford's Website and there are also insightfull videos in YUI Theater - start with the ones of Douglas. He's the one who discovered JavaScript has good parts. I also found John Resig's Secrets of the JavaScript Ninja very helpfull for grocking the language (John is the creator of the omnipresent jQuery Library). I would further advise you to look at some libraries (and their code - that's how I learned it - just start with jQuery). There are a ton of other libraries out there but one step at a time :-).
Now to your question:
The Backbone.Model is a constructor function, normally you would use it like in Java new Backbone.Model({ configOption: true, ... }). But juicy as JavaScript is it allows you to do crazy things under the hood. For example you can implement your own OOP Class implementation or you can program in a functional style like you would do in Scheme or Lisp. What you see here is Backbone's own subtyping wrapper in action (virtually any decent JS library provides some way to do this).
The code is actually doing something along the lines of this:
// Creating a sub type of the Backbone.Model *class* - it's not really
// a class like in Java or C# but rather a (constructor) function.
var Person = Backbone.Model.extend({
defaults: {
hasTheOneRing: true
},
initialize: function (hasTheOneRing) {
// Note that Backbone is implementing getters/setters
// under the hood so you can listen for change events later
this.set('hasTheOneRing', hasTheOneRing);
}
// More configuration ...
});
// Person now is a constructor function that creates instances
// of it's *class* when you create an object with it
var frodo = new Person(true),
sam = new Person(); // Note that you can supply as many arguments as you wish
// Frodo has the ring
console.log(frodo.get('hasTheOneRing'));
// Sam doesn't have the ring (well not all the time)
console.log(sam.get('hasTheOneRing'));
// In plain old JavaScript the sub typing mechanism works a little bit like this:
// A constructor function is just a function
function Person() {
// JS doesn't have the notion of *super* or *base* but you
// can emulate the behavior as many libraries do in the wild
Backbone.Model.call(this);
}
// The prototype of a person is based on that of a Backbone.Model
Person.prototype = Object.create(Backbone.Model.prototype);
// Object.create has not been there since the beginning. After
// Douglas Crockford discovered the good parts this function
// has been adapted into the standard portfolio of every modern browser
// what it does is essentially just:
function create(object) {
// There's actually more going on in here but you get the idea
function F() {}
F.prototype = object;
return new F();
}
// So this means almost the same
Person.prototype = new Backbone.Model();
My way of getting to love JS was to read library code - and Backbone is open source so have a read and be amazed by the awesomeness g. I think the fact that JS is just plain text send over the wire had a big influence on the language getting that strong in the ecosystem, even Microsoft couldn't stop it.
Give the language a try, when it clicks you'll most likely actually begin to like it :-).
Happy coding!
Related
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.
I am new to JavaScript (started learning it this week). I've completed the CodeCademy course (actually just Objects 1 && 2 parts, rest was boring). I thought I learned prototypal inheritance with constructors, but than I've started watching Douglas Crockford: Advanced JavaScript
Right at the beginning of the video, he mentions 2 types of inheritance, and I've realized, everything I thought I knew, I don't know. So I've started playing with Chrome JavaScript console and tried to do something using both inheritance models.
//create constructor
function MyParent(){
this.name = "joe";
this.sayHi = function(){
console.log(this.name);
}
}
//create child object and inherit from parent
var myChild1 = new MyParent();
myChild1.name
"joe"
myChild1.sayHi()
joe
//add method to MyParent, so it can be accessed from myChild1
MyParent.prototype.sayBye = function(){ console.log("bye");}
myChild1.sayBye()
bye
//create another constructor
function MyParent2(){
this.sayHi = function(){
console.log("hi");
}
}
//make it inherit from MyParent, overwriting sayHi if object is instance of MyParent2
MyParent2.prototype = new MyParent();
//overwrote sayHi
var myChild11 = new MyParent2();
myChild11.sayHi();
hi
//still same as MyParent as its not overwriten in MyParent2
myChild11.name
"joe"
Than I've tried to do the same thing using Object.create:
//create an object
var myParent = {
name : "joe",
sayHi : function(){
console.log(this.name)
}
};
//it works
myParent.sayHi()
joe
//create child object
var myChild = Object.create(myParent);
myChild.sayHi()
joe
//add bye method to myChild
myChild.sayBye = function(){ console.log("bye"); }
myChild.sayBye();
bye
//add bye method to myParent - does not overwrite child's bye
myParent.sayBye = function(){ console.log("bye2"); }
//however adding sayBye2 to parent, becomes available on already created child
myParent.sayBye2 = function(){ console.log("bye2"); }
myChild.sayBye2();
bye2
//but its the parent property
myChild.hasOwnProperty("sayBye2")
false
//could make million objects inherit from each other vertically or horizontally
var myChild2 = Object.create(myChild);
myChild2.name
"joe"
So far, just by first impression, I do like both models, maybe I slightly prefer the latter. It seems to be more expressive and powerful.
I've done some search on the vs. topic, but couldn't find a good article, that would explain pros and cons of each approach (other than latter is supported by newer browsers only, but there is a simple workaround). Rest of the posts I found were just tl: dr; and somewhat boring.
So my question is, which type of inheritance should I go with. Are there any perks associated with either? Any major cons for either? Can you mixin both? (eg. I know you can pass object as argument into new Constructor()))
Thanks
EDIT:
Looking at trick to create Object.create() alternative if browser doesn't support it, I realized how simple the hack is. It is basically creating an empty constructor, assigning parent object as its prototype and returning the built constructor as new object. What a neat hack!
if(typeof Object.create !== "function") { Object.create = function (o) { function F() {}; F.prototype = o; return new F(); }; }
But what are the implications? Any gotchas to be aware of?
Both ways are equally powerful. Some says that you are not a real JavaScript master if you do not embrace the pure prototypal approach, but really everything is still just prototypal inheritance and it's a matter of style.
Personnaly, I prefer using a classical approach and make use of the new keyword together with a constructor function.
Why?
The classical model is very well-know.
I don't have to implement an init function on my objects only to do what a constructor does already. As you probably noticed, the pure prototypal approach leaves you without a constructor so you will have to implement an initialization function (generally called init) if you need to run some initialization logic for newly created objects.
However, I find that the pure prototypal approach is a bit less verbose and might be easier to understand for programmers without a strong background with languages implementing classical inheritance.
By the way, one thing you should avoid with the classical model is to inherit using the new keyword like you are doing above because you are running the parent constructor logic unnecessary and it could potentially have undesirable side-effects.
You should be using Object.create like below:
function A(val) { this.val = val; }
A.prototype.alertVal = function () { alert(this.val); };
function B(val) {
A.call(this, val); //call parent constructor
}
B.prototype = Object.create(A.prototype); //inherit from A
var b = new B('test');
b.alertVal(); //test
At the end, it's all a matter of taste and I respect both ways. Maybe someone else will want to improve this answer with some real advantages/disadvantages, but I cannot find any.
Constructing objects with new was pronounced evil, because you can forget to use it and then whatever properties you add to this will end up added to the global object. For this reason I am in for the second approach.
One other thing I have learnt is that you should not try to apply "classical" OOD to JavaScript. It has its own way that should be understood and it is quite nice in fact. I think most of object programming problems in JavaScript come from attempts to stretch notion of "class" onto JavaScript.
I just wrote some JavaScript code that follows along with what I believe to be good practice for creating an object with closure and some functions:
var myStuff = (function() {
var number = 0;
var fn = {};
fn.increment = function() { number++; };
fn.decrement = function() { number--; };
fn.getNumber = function() { return number; };
return fn;
})();
myStuff.increment();
myStuff.increment();
alert(myStuff.getNumber()); // alerts '2'
I have no problem writing code like the previous snippet. I would like to write some code with functionality similar to a OOP "abstract" class. Here is the result of my effort:
var myStuff = (function () {
var number = 0;
var fn = {};
fn.increment = function () { number++; };
fn.decrement = function () { number--; };
fn.doSomethingCrazy = function () { throw new Error('not implemented'); }; // I want to specify later what this does.
fn.doSomethingCrazyTwice = function () { fn.doSomethingCrazy(); fn.doSomethingCrazy(); };
fn.getNumber = function () { return number; };
return fn;
})();
myStuff.doSomethingCrazy = function () { this.increment(); this.increment(); };
myStuff.doSomethingCrazyTwice();
alert(myStuff.getNumber()); // alerts '4'
The above code snippet works, but it doesn't seem graceful. Perhaps I'm trying to force JavaScript (a functional language) to do something it isn't designed to do (object inheritance)
What is a good way to define an object in JavaScript so that a function of that object can be defined later?
Just don't define the function.
Javascript is a duck-typed language. If it looks like a duck and it quacks like a duck, it is a duck.
You don't need to do anything special to make this work; as long as the function exists when you call it, it will work fine.
If you call it on an instance that doesn't have the function, you'll get an error at the callsite.
I agree with SLaks, there's no need to define the function, but I tend to anyway. That's because to me the important part is in the documentation. When somebody reads my class, I want it to be clear that you must implement these methods, what arguments will be passed and what should be returned.
This is from a file at work. There were multiple implementations of a feature with a base class that did the data loading at intervals.
/**
* Called when data is received and should update the data buffer
* for each of the charts
*
* #abstract
* #param {cci.ads.Wave[]} waves
* #void
*/
updateChartsData: function(waves){
throw "Abstract method updateChartsData not implemented";
},
2019 Update
Use TypeScript if you can Declaring abstract method in TypeScript
As our team is growing and our javascript project is getting more complex we have to start implementing OO features as well.
In our javascript 'abstract' method we simply throw an error, or pop up an alert. This is an example from out Page object:
Page.initialLoad = function() { //abstract
alert('Page.initialLoad not implemented');
};
In java world it is analagous to :
public void abstract initialLoad();
The Java code gives a compile time error, however in the Javascript we would get a runtime error. (a dirty error dialog saying that an implementing object hasn't implemented that method yet).
We have a number of disparate teams that use the Page object; the philosophy of 'duck typing' absolutely does not cut it with us. Without these pseudo 'abstract' methods we have a general lack of API communication, and sometimes we get sabotaging of the super object (ie. because a user has no idea they are supposed to implement the method).
I am tired of this 'duck typing' philosophy. I'm not sure if proponents have ever been in a complex Javascript project with 10+ developers.
If you don't find your way graceful there is probably a way to create some functions to stramline the process to make it look better. But back to the topic...
Yes, Javascript has builtin delegation, aka inheritance, via prototypes.
Given a prototypal object:
var proto = {
f: function(){ console.log(this.x); }
}
We can create a new object that inherits from it:
var obj = Object.create(proto);
obj.x = 42;
obj.f(); //should work!
for(var i in obj) console.log(i);
//should print x, f and some other stuff perhaps
Just note, that doing things directly via Object.create is not always supported (old browsers, etc). The old (and some may say, normal) way do do stuff is via the funky new operator (don´t think too much on the name - its confusing on purpose to distract the Java people)
function Constructor(arg){
this.x = arg;
}
Constructor.prototype = {
f: function(){ ... }
};
var obj = new Constructor(17);
obj.f();
An important difference to consider with prototypical inheritance is the lack of private variables. Only public variables can be inherited! Because of this, a common convention is to use underscore as a prefix for private and protected variables.
You might want to take a look at this previous post How do I create an abstract base class in JavaScript?
Just a few sites for some light reading for you on OOP and JavaScript, I am assuming that your new to JavaScript as an OOP langauge based of a comment you said
http://mckoss.com/jscript/object.htm
http://www.codeproject.com/KB/aspnet/JsOOP1.aspx
http://www.javascriptkit.com/javatutors/oopjs.shtml
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.
Just finished reading Crockford's "JavaScript: The Good Parts" and I have a question concerning his stance on the psuedo-classical vs. prototypal approaches. Actually I'm not really interested in his stance; I just want to understand his argument so I can establish a stance of my own.
In the book, Crockford seems to infer that constructor functions and "all that jazz" shouldn't be used in JavaScript, he mentions how the 'new' keyword is badly implemented - i.e. non-Constructor functions can be called with the 'new' keyword and vice versa (potentially causing problems).
I thought I understood where he was coming from but I guess I don't.
When I need to create a new module I would normally start of like this:
function MyModule(something) {
this.something = something || {};
}
And then I would add some methods to its prototype:
MyModule.prototype = {
setSomething : function(){},
getSomething : function(){},
doSomething : function(){}
}
I like this model; it means I can create a new instance whenever I need one and it has its own properties and methods:
var foo = new MyModule({option1: 'bar'});
// Foo is an object; I can do anything to it; all methods of the "class"
// are available to this instance.
My question is: How do I achieve the above using an approach more suited to JavaScript? In other words, if "JavaScript" were a person, what would she suggest?
Also: What does Crockford mean when he says a particular design pattern "is more expressive" then another?
See: Is JavaScript's “new” Keyword Considered Harmful?
It's important to remember that Crockford, like so many other JavaScript programmers, first approached the language with an eye toward "fixing" it - making it more like other (so-called "classical") OO languages. So a large amount of structural code was written, libraries and frameworks built, and... then they started to realize that it wasn't really necessary; if you approach JS on its own terms, you can get along just fine.
The prototypal variant for the example you have looks like the following in my understanding:
Object.beget = function (o) { /* Crockfords replacement for the new */ }
var myModule = {
something : null,
getSomething : function () {},
setSomething : function () {},
doSomething : function () {}
};
And then you can do:
var foo = Object.beget(myModule);
foo.something = bar;
UPDATE: You can also use the builder pattern to replace a constructor like this:
var myModuleBuilder = {
buildMyModule : function (something) {
var m = Object.beget(myModule);
m.something = something || {};
return m;
}
}
so then you can do:
var foo = myModuleBuilder.buildMyModule(something);
Your implementation is problematic because you're replacing the entire prototype object, losing the properties of the inherited function prototype and it would also break, or at least make it more difficult, the ability to make use of inheritance later on if you wrote other classes the same way.
A method more suited to Javascript would be:
var MyClass = function (storeThis) {
this.storage = storeThis
}
MyClass.prototype.getStorage = function (){
return this.storage;
}
MyClass.prototype.setStorage = function (newStorage){
this.storage = newStorage;
}
Use it:
var myInstance = new MyClass("sup");
alert("myInstance storage: " + myInstance.getStorage());
myInstance.setStroage("something else");
As for the 'new' keyword and Crawford's problems with it, I can't really answer, because I haven't read the book, but I can see how you could create a new object by calling any function with the new keyword, including functions that are supposed to be methods of a class.
And when someone says something, such as a design pattern, is more 'expressive', he or she generally means that the design pattern is clear and simple to understand as to what it is achieving and how.
Javascript isn't a person so she can't really suggest what you do.
None of the answers above have mentioned the plain-old functional style of inheritance, which I tend to find is the simplest.
function myModuleMaker(someProperty){
var module = {}; //define your new instance manually
module.property = someProperty; //set your properties
module.methodOne = function(someExternalArgument){
//do stuff to module.property, which you can, since you have closure scope access
return module;
}
}
Now to make a new instance:
var newModule = myModuleMaker(someProperty);
You still get all the benefits of pseudoclassical this way, but you suffer the one drawback that you're making a new copy of all your instance's methods every time you instantiate. This is probably only going to matter when you start having many hundreds (or indeed, thousands) of instances, which is a problem most people seldom run into. You're better off with pseudoclassical if you're creating truly enormous data structures or doing hard-core animations with many, many instances of something.
I think it's hard to argue that either method is "bad practice" per se.