I've been working with node.js for a while on a chat app (I know, very original, but I figured it'd be a good learning project). Underscore.js provides a lot of functional programming concepts which look interesting, so I'd like to understand how a functional program in JavaScript would be setup.
From my understanding of functional programming (which may be wrong), the whole idea is to avoid side effects, which are basically having a function which updates another variable outside of the function so something like
var external;
function foo() {
external = 'bar';
}
foo();
would be creating a side effect, correct? So as a general rule, you want to avoid disturbing variables in the global scope.
Ok, so how does that work when you're dealing with objects and what not? For example, a lot of times, I'll have a constructor and an init method that initializes the object, like so:
var Foo = function(initVars) {
this.init(initVars);
}
Foo.prototype.init = function(initVars) {
this.bar1 = initVars['bar1'];
this.bar2 = initVars['bar2'];
//....
}
var myFoo = new Foo({'bar1': '1', 'bar2': '2'});
So my init method is intentionally causing side effects, but what would be a functional way to handle the same sort of situation?
Also, if anyone could point me to either a Python or JavaScript source code of a program that tries to be as functional as possible, that would also be much appreciated. I feel like I'm close to "getting it", but I'm just not quite there. Mainly I'm interested in how functional programming works with traditional OOP classes concept (or does away with it for something different if that's the case).
You should read this question:
Javascript as a functional language
There are lots of useful links, including:
Use functional programming techniques to write elegant JavaScript
The Little JavaScripter
Higher-Order JavaScript
Eloquent JavaScript, Chapter 6: Functional Programming
Now, for my opinion. A lot of people misunderstand JavaScript, possibly because its syntax looks like most other programming languages (where Lisp/Haskell/OCaml look completely different). JavaScript is not object-oriented, it is actually a prototype-based language. It doesn't have classes or classical inheritance so shouldn't really be compared to Java or C++.
JavaScript can be better compared to a Lisp; it has closures and first-class functions. Using them you can create other functional programming techniques, such as partial application (currying).
Let's take an example (using sys.puts from node.js):
var external;
function foo() {
external = Math.random() * 1000;
}
foo();
sys.puts(external);
To get rid of global side effects, we can wrap it in a closure:
(function() {
var external;
function foo() {
external = Math.random() * 1000;
}
foo();
sys.puts(external);
})();
Notice that we can't actually do anything with external or foo outside of the scope. They're completely wrapped up in their own closure, untouchable.
Now, to get rid of the external side-effect:
(function() {
function foo() {
return Math.random() * 1000;
}
sys.puts(foo());
})();
In the end, the example is not purely-functional because it can't be. Using a random number reads from the global state (to get a seed) and printing to the console is a side-effect.
I also want to point out that mixing functional programming with objects is perfectly fine. Take this for example:
var Square = function(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
};
function getArea(square) {
return square.w * square.h;
}
function sum(values) {
var total = 0;
values.forEach(function(value) {
total += value;
});
return total;
}
sys.puts(sum([new Square(0, 0, 10, 10), new Square(5, 2, 30, 50), new Square(100, 40, 20, 19)].map(function(square) {
return getArea(square);
})));
As you can see, using objects in a functional language can be just fine. Some Lisps even have things called property lists which can be thought of as objects.
The real trick to using objects in a functional style is to make sure that you don't rely on their side effects but instead treat them as immutable. An easy way is whenever you want to change a property, just create a new object with the new details and pass that one along, instead (this is the approach often used in Clojure and Haskell).
I strongly believe that functional aspects can be very useful in JavaScript but ultimately, you should use whatever makes the code more readable and what works for you.
You have to understand that functional programming and object oriented programming are somewhat antithetical to each other. It's not possible to both be purely functional and purely object oriented.
Functional programming is all about stateless computations. Object oriented programming is all about state transitions. (Paraphasing this. Hopefully not too badly)
JavaScript is more object oriented than it is functional. Which means that if you want to program in a purely functional style, you have to forego large parts of the language. Specifically all the object orient parts.
If you are willing to be more pragmatic about it, there are some inspirations from the purely functional world that you could use.
I try to adhere to the following rules:
Functions that perform computations should not alter state. And functions that alter state should not perform computations. Also, functions that alter state should alter as little state as possible. The goal is to have lots of little functions that only do one thing. Then, if you need to do anything big, you compose a bunch of little functions to do what you need.
There are a number of benefits to be gained from following these rules:
Ease of reuse. The longer and more complex a function is, the more specialized it also is, and therefore the less likely it is that it can be reused. The reverse implication is that shorter functions tend to more generic and therefore easier to reuse.
Reliability of code. It is easier to reason about correctness of the code if it is less complex.
It is easier to test functions when they do only one thing. That way there are fewer special cases to test.
Update:
Incorporated suggestion from comment.
Update 2:
Added some useful links.
I think, http://documentcloud.github.com/underscore/ should be nice fit for what you need - it provides the most important higher-order functions for functional programming and does not has client-side functions for DOM manipulation which you don't need for server side. Though I don't have experience with it.
As a side note: IMHO primary feature of functional programming is Referential transparency of a function - function result depends only on its parameters - function does not depend on changes on other objects and does not introduce any change except its result value. It makes it easy to reason about program's correctness and very valuable for implementing of predictable multi-threading (if relevant). Though JavaScript is not the bet language for FP - I expect immutable data structures to be very expensive performance-wise to use.
So 2 things to point out ,
In your first example your variable would not be leaking into the global area and is the way it should be done , try to never use variables without declaring them i.e. test = 'data' would cause data to leak into the global area.
Your second example is correct as well , bar1 and bar2 would only be declared on the Foo object.
Things to keep in mind try not to overuse prototyping since it applies to every object that you create , this could be extremely memory intensive depending on how complex your objects are.
If you are looking for a app development framework , have a look at ExtJs. Personally I think it would fit perfectly into the model you are trying to develop against. Just keep in mind how their licensing model works before getting heavily invested in it.
Related
Is it worth using mini functions in JavaScript? Example:
function setDisplay(id, status) {
document.getElementById(id).style.display = status;
}
And after that, each time you want to manipulate the display attribute of any given object, you could just call this function:
setDisplay("object1", "block");
setDisplay("object2", "none");
Would there be any benefit of coding this way?
It would reduce file size and consequently page load time if that particular attribute is changed multiple times. Or would calling that function each time put extra load on processing, which would make page loading even slower?
Is it worth using mini functions in JavaScript?
Yes. If done well, it will improve on:
Separation of concern. For instance, a set of such functions can create an abstraction layer for what concerns presentation (display). Code that has just a huge series of instructions combining detailed DOM manipulation with business logic is not best practice.
Coding it only once. Once you have a case where you can call such a function more than once, you have already gained. Code maintenance becomes easier when you don't have (a lot of) code repetition.
Readability. By giving such functions well chosen names, you make code more self-explaining.
Concerning your example:
function setDisplay(id, status) {
document.getElementById(id).style.display = status;
}
[...]
setDisplay("object1", "block");
setDisplay("object2", "none");
This example could be improved. It is a pity that the second argument is closely tied to implementation aspects. When it comes to "separation of concern" it would be better to replace that argument with a boolean, as essentially you are only interested in an on/off functionality. Secondly, the function should probably be fault-tolerant. So you could do:
function setDisplay(id, visible) {
let elem = document.getElementById(id);
if (elem) elem.style.display = visible ? "block" : "none";
}
setDisplay("object1", true);
setDisplay("object2", false);
Would there be any benefit of coding this way?
Absolutely.
would [it] reduce file size...
If you have multiple calls of the same function: yes. But this is not a metric that you should be much concerned with. If we specifically speak of "one-liner" functions, then the size gain will hardly ever be noticeable on modern day infrastructures.
...and consequently page load time
It will have no noticeable effect on page load time.
would calling that function each time put extra load on processing, which would make page loading even slower?
No, it wouldn't. The overhead of function calling is very small. Even if you have hundreds of such functions, you'll not see any downgraded performance.
Other considerations
When you define such functions, it is worth to put extra effort in making those functions robust, so they can deal gracefully with unusual arguments, and you can rely on them without ever having to come back to them.
Group them into modules, where each module deals with one layer of your application: presentation, control, business logic, persistence, ...
It would reduce file size and consequently page load time if that particular attribute is changed multiple times. Or would calling that function each time put extra load on processing, which would make page loading even slower?
It won't make the page's loading slower. Adding a few lines here and there with vanilla js won't effect the page loading time, after all, the page's loading time is the time to load the html js and css files, so a few lines in js won't effect it. A performance issue is unlikely to happen unless you're doing something really intended that brings you into a massive calculation or huge recursion.
Is it worth using mini functions in JavaScript?
In my opinion - Yes. You don't want to overuse that when unnecessary, after all, you don't want to write each line of code in a function right? In many cases, creating mini functions can improve the code's cleanness, readability and they can made it easier and faster to code.
With es6 you can use a single line functions with is very nice and easy:
const setDisplay = (id, status) => document.getElementById(id).style.display = status;
It doesn't really affect the performance unless you execute that function 10,000 or more times.
Jquery use mini functions, like $('#id').hide(); $('#id').show(); and $("#id").css("display", "none"); $("#id").css("display", "block");
It creates more readable code but it doesn't do that much to the performance.
var divs = document.querySelectorAll("div");
function display(div, state) {
div.style.display = state;
}
console.time("style");
for(var i = 0; i < divs.length; i++) {
divs[i].style.display = "none";
}
console.timeEnd("style");
console.time("function");
for(var j = 0; j < divs.length; j++) {
display(divs[j], "block");
}
console.timeEnd("function");
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
In terms of runtime performance I’d say it doesn’t make any difference. The JavaScript engines are incredibly optimized and are able to recognize that this function is being called often and to replace it by native code, and maybe even able to inline the function call so that the cost of calling an extra function is eliminated completely.
If your intent is to reduce the JavaScript files: you save a few tens of bytes for each place in the code where the function can be used, but even if you call this mini function 100 times, you will be saving 1 or 2 kb of uncompressed JavaScript. If you compare the final gzipped JavaScript (which should be how you serve your resources if you care about performance) I doubt there will be any noticeable difference.
You also need to think about how this type of code will be understood by your colleagues, or whoever may have to read this code in the future. How likely it is that a new programmer in your team knows the standard DOM API? Your non-standard functions might confuse your future teammates, and require them to look into the function body to know what they do. If you have one function like this it probably doesn’t make much of a difference, but as you start adding more and more mini functions for each possible style attribute you end up with hundreds of functions that people need to get used to.
The real benefit is ability to update on several places. Let say that you realize that you want to use classes instead of using styles. Instead of having to change on all places, you can just change that one method.
This is even more apparent when you read from a common source. Perhaps you have an API that you call with a single method.
let user = getData('user');
...but instead doing a API call, you want to use localforage to store the user data and read from the disk instead.
let user = getData('user');
... but you realized that it takes about 70-200 ms to read from localforage, so instead you store everything in memory, but reading from localforage if it's not in memory, and doing an API call if it's not in localforage. Getting user information is still the same:
let user = getData('user');
Just imagine if you wrote the whole call in every single place.
I usually create mini functions like these if I 1) read/write data, 2) if the code gets shorter OR more readable (i.e. the method name replaces comments), 3) or if I have repeatable code that I can sum up in a dynamic way.
Also, to quote from the book Clean Code: each function should do only one thing. Thinking in terms of mini functions helps with that.
I'm not fully sure of what a mini function is but if you're asking whether it's better to define functions for code that needs to be called multiple times instead of typing out/ copy-pasting those same lines of code over and over then it's better to go with option 1 for readability and file-size.
It would reduce file size and consequently page load time if that particular attribute is changed multiple times. Or would calling that function each time put extra load on processing, which would make page loading even slower?
It's not in typical scenarios possible for the usage of such functions to put (any significant) extra load on processing that would slow down the document parsing, it's likeliness to do that would however depend on when and how you call your code to be executed but it's not like you'll be looping O(N3) and calling such functions thousands of times to impact page loading (right?) - if anything, predefined functions like that meant to take dynamic inputs would make your code neater, more uniform looking and reduce file-size... with a very tiny obvious overhead when compared to directly accessing properties without having to go through another function. So you decide whether you want to take up that bargain depending on whether the frequency of you calling functions like that would be significant enough to be considered.
I'm sure most engines optimize repetitive code so it's (or nearly) equivalent to the same thing anyway so I'd choose readability and improve how easy it is for others to understand and follow through code instead.
JavaScript is prototype language on top of that going on a leaf to say everything in JavaScript is an object so its object oriented as object oriented gets to be although at a very different level.
So the question is like we create classes in object oriented, would we develop script framework as functional programming or prototype and what will be performance hit.
so lets consider this very fine example.
function abc(name, age) {
this.name = name;
this.age = age;
}
person1 = new abc('jhon', 25);
person2 = new abc('mark', 46);
console.log(person1.age);console.log(person2.age);
person1.father = 'mark';
console.log(person1.father);
we have created a function and have used the power of this in the scope of function thus every new insurance will carry this information. and no two instances will be alike.
Then down the a line we have used prototype to add father information on instance. This where prototyping becomes awesome. Thus whole this scoping + instance + prototyping is fast.
function abc(name, age) {
name = name;
age = age;
return name; // its either name or age no two values
}
person1 = abc('jhon', 25);
person2 = abc('mark', 46);
console.log(person1);
console.log(person2);
abc.father = 'mark';
console.log(person1.father);
console.log(abc.father);
we tried the same on functional sense the whole thing fell apart. no instance + no this scoping + no new prototyping delegating down the line. Thus in long run this approach will reduce performance as one would have to re-fetch things over and over again on top of that with t=out this scoping we are only returning single factor where as with this scooping we are packing a lot more into object. this one point.
function abc(name, age) {
this.name = name;
this.age = age;
}
person1 = new abc('jhon', 25);
person1.fatherName = 'Mark';
person1.fatherUpdate = function (d){this.fatherAge = this.fatherName+' '+d;};
person1.fatherUpdate(56);
console.log(person1.fatherAge);
Now have added more complexity we have carried this down the line hence the scope and have added functions on top of it.
This will literally make your hair fall out if things were done in pure functional way.
Always keep in mind any given function can and may compute and execute as many things you want but it will always give single return with 99% of the time single property.
If you need more prototype way with scoping as above.
jquery way of doing things.
I had made my framework ActiveQ which uses the above its almost 30 Kb unminified and does everything jquery does and much more with template engine.
anyways lets build example - it is an example so please be kind ;
function $(a){
var x;
if(x = document.querySelector(a)) return x;
return;}
console.log($('div'));
console.log($('p'));
<div>abc</div>
Now this almost 50% of your jquery selector library in just few lines.
now lets extended this
function $(a){
this.x = document.querySelector(a);
}
$.prototype.changeText = function (a){
this.x.innerHTML = a;
}
$.prototype.changeColor = function (a){
this.x.style.color = a;
}
console.log(document.querySelector('div').innerText);
app = new $('div');
app.changeText('hello');
console.log(document.querySelector('div').innerText);
app.changeColor('red');
<div>lets see</div>
what was the point of the whole above exercise you wont have to search through DOM over and over again as long as long one remains in scope of the function with this
Obviously with pure functional programming one would have to search though all over again and again.
even jquery at time forgets about what it had searched and one would have to research because this context is forwarded.
lets do some jquery style chaining full mode way - please be kind its jusrt an example.
function $(a){
return document.querySelector(a);
}
Element.prototype.changeText = function (a){
this.innerHTML = a;
return this;
}
Element.prototype.changeColor = function (a){
this.style.color = a;
return this;
}
console.log($('div').innerText);
//now we have full DOm acces on simple function reurning single context
//lets chain it
console.log($('div').changeText('hello').changeColor('red').innerText);
<div>lets see</div>
See the difference less line of code is way faster in performance as its working with the browser rather then pure functional way rather then creating a functional call load and search load all repeatedly
so you need to perform bunch of tasks with single output stick to functions as in conventional way and if you need to perform bunch of tasks on context as in last example where context is to manipulate properties of the element as compared to $ function which only searches and returns the element.
I come from a C# background. I've been working a lot with JavaScript lately. On a new app, I have a mysql/php back end. I'm going to be passing a lot of "types" back and forth.
So in my data base, I have several tables like
table1
id, fieldx,fieldy,fieldz
table2
id, fielda,fieldb,fielc
In c# I would definitely write classes for all those in the code. Which led me to implement things like so (in my JavaScript app):
function table1(id, x,y,z){
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
After about 6 tables worth of that, it suddenly occurred to me that maybe there was no point at all in making these classes.
So my question is, in a JavaScript app, do I use "classes" for data types? or should I just "document" which fields/types are expected and so in the code instead of
a.push(new table1(5,1,2,3));
I would just have
a.push({id:5,x:1,y:2,z:3});
This may seem like a preferences question but it's a fundamental language question that I have as I try to understand how to model my app's data in JavaScript. Is there any advantage of the classes (with only data fields) or is it just a mistake. Thanks.
It depends,
Note: Most of the programmers coming from a strong OO language will have trouble like you in regard to JavaScript's functional behavior (you are not alone).
If you want to create something closer to C# I would do the following:
function Table1(id, x, y, z) {
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
Table1.prototype.mySpecialTable1Method= function()
{
console.log(this.id);
};
Implementation:
var t = new Table1(1, 2, 3, 4);
t.mySpecialTable1Method();// outputs: 1
If you need to have methods that interact with the (soon to be) objects then I would definitely go with the code above. In addition it will make it clear when working with the objects that are related to a specific 'type' (naming the data).
But if your objects do not require any special "treatment" then I don't see any problem to use normal js object literals and pass them along (probably good for small projects).
Something along the lines:
var table1 = {};
table1.id = 1;
table1.x = 2;
table1.y = 3;
table1.z = 4;
console.log(table1.id); //outputs: 1
Extra reference:
http://www.youtube.com/watch?v=PMfcsYzj-9M
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
Update:
For the sake of readability and scalability and the point that you are coming from C# you may want to stick to the "class" implementation just because it will define the correlation between the raw data and the objects you are working with.
There is a good chance that you are going to work with some data that will probably be messy and unorganized.
MVC may be the solution for you. It tries to bring some order to the chaos that you are expecting. I recommend to check out some of them like: AngularJS or Ember.
Another solution may be reactive js - but mostly if you are going to interact with the DOM according to your data (ReactJS, and Facebook's React as some good ones).
As a note for security, I would like to add that mapping the data closely to the db isn't a best practice but its your call.
Javascript is a funny language, and there are plenty of ways to do things. An Object is an Object in Javascript with or without a name. {} is just a short-hand way to create one.
If you are going for readability, then your initial example would be the way to go.
If you just want to get the block of data into an array, then your second example is appropriate. Personally, I would use your later example if it is just data.
If you are using functions and what not as well as data storage, and plan on reusing it several times in your code, then yes, define your object and call it appropriately.
JavaScript has no classes, it is a functional language and a function is a first class citizen in js meaning that a function is an object.
From your example I can see that your intention for classes is simply to pass data and using json is perfect for this.
The javascript prototype-based object-oriented programming style is interesting, but there are a lot of situations where you need the ability to create objects from a class.
For instance in a vector drawing application, the workspace will usually be empty at the beginning of the drawing : I cannot create a new "line" from an existing one. More generally, every situation where objects are being dynamically created require the use of classes.
I've read a lot of tutorials and the book "Javascript : the good parts", but yet it seems to me that there is no way to define classes that respect 1) encapsulation and 2) efficient member methods declaration (I mean : member methods that are being defined once, and shared among every class instances).
To define private variables, closures are being used :
function ClassA()
{
var value = 1;
this.getValue = function()
{
return value;
}
}
The problem here is that every instance of "ClassA" will have its own copy of the member function "getValue", which is not efficient.
To define member functions efficiently, prototype is being used :
function ClassB()
{
this.value = 1;
}
ClassB.prototype.getValue = function()
{
return this.value;
}
The problem here is that the member variable "value" is public.
I don't think that this issue can be solved easily, since "private" variables need to be defined DURING object creation (so that the object can have access to its context of creation, without exposing thoses values) whereas prototype-based member functions definition has to be done AFTER object creation, so that prototype makes sense ("this.prototype" does not exists, I've checked).
Or am I missing something ?
EDIT :
First of all, thank you for your interesting answers.
I just wanted to add a little precision to my initial message :
What I really want to do is to have 1) private variables (encapsulation is good, because people only have access to what they need) and 2) efficient member methods declaration (avoid copies).
It seems that simple private variables declaration can really only be achieved via closure in javascript, that's essentially why I focused on the class based approach. If there is a way to achieve simple private variables declaration with a prototype based approach, that's okay for me, I'm not a fierce class-based approach proponnent.
After reading the answers, it seems like the simple solution is to forget about privates, and use a special coding conventions to detter other programmers from accessing "private" variables directly...
And I agree, my title / first sentence was misleading regarding the issue I wanted to discuss here.
Shh, come here! Wanna hear a secret?
Classical inheritance is a tested and tried approach.
It is useful to implement it in JavaScript often. Classes are a nice concept to have and having templates for modeling our world after objects is awesome.
Classical inheritance is just a pattern. It's perfectly OK to implement classical inheritance in JavaScript if it's the pattern you need for your use case.
Prototypical inheritance focuses on sharing functionality and that's awesome (dinasaur drumstick awesome), but in some cases you want to share a data-scheme and not functionality. That's a problem prototypical inheritance does not address at all.
So, you're telling me classes are not evil like everyone keeps telling me?
No, they are not. What the JS community frowns upon is not the concept of classes, it's limiting yourself to just classes for code reuse. Just like the language does not enforce strong or static typing, it doesn't enforce schemes on object structure.
In fact, behind the scene clever implementations of the language can turn your normal objects to something resembling classical inheritance classes.
So, how do classes work in JavaScript
Well, you really only need a constructor:
function getVehicle(engine){
return { engine : engine };
}
var v = getVehicle("V6");
v.engine;//v6
We now have a vehicle class. We didn't need to define a Vehicle class explicitly using a special keyword. Now, some people don't like to do things this way and are used to the more classical way. For this JS provides (silly imho) syntactic sugar by doing:
function Vehicle(engine){
this.engine = engine;
}
var v = new Vehicle("V6");
v.engine;//v6
That's the same thing as the example above for the most part.
So, what are we still missing?
Inheritance and private members.
What if I told you basic subtyping is very simple in JavaScript?
JavaScript's notion of typing is different than what we're used to in other languages. What does it mean to be a sub-type of some type in JS?
var a = {x:5};
var b = {x:3,y:3};
Is the type of b a sub type of the type of a? Let's say if it is according to (strong) behavioral subtyping (the LSP):
<<<< Begin technical part
Contravariance of method arguments in the subtype - Is fully preserved in this sort of inheritance.
Covariance of return types in the subtype - Is fully preserved in this sort of inheritance.
No new exceptions should be thrown by methods of the subtype, except where those exceptions are themselves subtypes of exceptions thrown by the methods of the supertype. - Is fully preserved in this sort of inheritance.
Also,
Preconditions cannot be strengthened in a subtype.
Postconditions cannot be weakened in a subtype.
Invariants of the supertype must be preserved in a subtype.
The history rule
All of these are again, are up to us to keep. We can keep them as tightly or loosly as we want, we don't have to, but we surely can.
So matter of fact, as long as we abide to these rules above when implementing our inheritance, we're fully implementing strong behavioral subtyping, which is a very powerful form of subtyping (see note*).
>>>>> End technical part
Trivially, one can also see that structural subtyping holds.
How would this apply to our Car example?
function getCar(typeOfCar){
var v = getVehicle("CarEngine");
v.typeOfCar = typeOfCar;
return v;
}
v = getCar("Honda");
v.typeOfCar;//Honda;
v.engine;//CarEngine
Not too hard, was it? What about private members?
function getVehicle(engine){
var secret = "Hello"
return {
engine : engine,
getSecret : function() {
return secret;
}
};
}
See, secret is a closure variable. It's perfectly "private", it works differently than privates in languages like Java, but it's impossible to access from the outside.
What about having privates in functions?
Ah! That's a great question.
If we want to use a private variable in a function we share on the prototype we need to firrst understand how JS closures and functions work.
In JavaScript functions are first class. This means you can pass functions around.
function getPerson(name){
var greeting = "Hello " + name;
return {
greet : function() {
return greeting;
}
};
}
var a = getPerson("thomasc");
a.greet(); //Hello thomasc
So far so good, but we can pass that function bounded to a around to other objects! This lets you do very loose decoupling which is awesome.
var b = a.greet;
b(); //Hello thomasc
Wait! How did b know the person's name is thomasc? That's just the magic of closures. Pretty awesome huh?
You might be worried about performance. Let me tell you how I learned to stop worrying and started to love the optimizing JIT.
In practice, having copies of functions like that is not a big issue. Functions in javascript are all about well, functionality! Closures are an awesome concept, once you grasp and master them you see it's well worth it, and the performance hit really isn't that meaningful. JS is getting faster every day, don't worry about these sort of performance issues.
If you think it's complicated, the following is also very legitimate. A common contract with other developers simply says "If my variable starts with _ don't touch it, we are both consenting adults". This would look something like:
function getPerson(name){
var greeter = {
greet : function() {
return "Hello" +greeter._name;
}
};
greeter._name = name;
return greeter;
}
Or in classical style
function Person(name){
this._name = name;
this.greet = function(){
return "Hello "+this._name;
}
}
Or if you'd like to cache the function on the prototype instead of instantiate copies:
function Person(name){
this._name = name;
}
Person.prototype.greet = function(){
return "Hello "+this._name;
}
So, to sum it up:
You can use classical inheritance patterns, they are useful for sharing types of data
You should also use prototypical inheritance, it is just as potent, and much more in cases you want to share functionality.
TheifMaster pretty much nailed it. Having privates private is really not a big deal as one might think in JavaScript, as long as your code defines a clear interface this should not be problematic at all. We're all concenting adults here :)
*The clever reader might think: Huh? Weren't you tricking me there with the history rule? I mean, property access isn't encapsulated.
I say no, I was not. Even if you don't explicitly encapsulate the fields as private, you can simply define your contract in a way that does not access them. Often like TheifMaster suggested with _. Also, I think the history rule is not that big of a deal in a lot of such scenarios as long as we're not changing the way property access treats properties of the parent object. Again, it's up to us.
I don't want to be discouraging since you seem to be a fairly new member of StackOverflow, however I'm going to have to be a little in your face and say that it's a really bad idea to try to implement classical inheritance in JavaScript.
Note: When I say that it's a bad idea to implement classical inheritance in JavaScript I mean that trying to simulate actual classes, interfaces, access modifiers, etc. in JavaScript is a bad idea. Nevertheless, classical inheritance as a design pattern in JavaScript is useful as it's just syntactic sugar for prototypal inheritance (e.g. maximally minimal classes). I use this design pattern in my code all the time (a la augment).
JavaScript is a prototypal object-oriented programming language. Not a classical object-oriented programming language. Sure, you can implement classical inheritance on top of JavaScript but before you do keep the following things in mind:
You're going against the spirit of the language, which means that you'll be faced with problems. Lots of problems - performance, readability, maintainability, etc.
You don't need classes. Thomas, I know that you truly believe that you need classes but trust me on this. You don't.
For your sake I'll provide two answers to this question. The first one will show you how to do classical inheritance in JavaScript. The second one (which I recommend) will teach you to embrace prototypal inheritance.
Classical Inheritance in JavaScript
Most programmers start with trying to implement classical inheritance in JavaScript. Even JavaScript Gurus like Douglas Crockford tried to implement classical inheritance in JavaScript. I too tried to implement classical inheritance in JavaScript.
First I created a library called Clockwork and then augment. However I wouldn't recommend you to use either of these libraries because they go against the spirit of JavaScript. The truth is that I was still an amateur JavaScript programmer when I wrote these classical inheritance libraries.
The only reason I mention this is because everyone is an amateur at some point of time, and although I would prefer that you didn't use classical inheritance patterns in JavaScript, I can't expect you to understand why prototypal inheritance matters just yet.
You can't learn how to cycle without falling down a few times. I believe you're still in the learning phase with respect to prototypal inheritance. Your need for classical inheritance is like the training wheels on cycles.
Nevertheless, training wheels are important. If you want there are some classical inheritance libraries out there which should make you more comfortable writing code in JavaScript. One such library is jTypes. Just remember to take off the training wheels when you are confident of your skills as a JavaScript programmer.
Note: Personally I don't like jTypes one bit.
Prototypal Inheritance in JavaScript
I'm writing this section as a milestone for you so that you can come back later and know what to do next when you are ready to learn about true prototypal inheritance.
First of all the following line is wrong:
The javascript prototype-based object-oriented programming style is interesting, but there are a lot of situations where you need the ability to create objects from a class.
This is wrong because:
You will never need to create objects from a class in JavaScript.
There is no way to create a class in JavaScript.
Yes it's possible to simulate classical inheritance in JavaScript. However you're still inheriting properties from objects and not classes. For example, ECMAScript Harmony classes are just syntactic sugar for the classical pattern of prototypal inheritance.
In the same context the example you gave is also wrong:
For instance in a vector drawing application, the workspace will usually be empty at the beginning of the drawing : I cannot create a new "line" from an existing one. More generally, every situation where objects are being dynamically created require the use of classes.
Yes you can create a new line from an existing one even though the workspace is empty in the beginning. What you need to understand is that the line is not actually drawn though.
var line = {
x1: 0,
y1: 0,
x2: 0,
y2: 0,
draw: function () {
// drawing logic
},
create: function (x1, y1, x2, y2) {
var line = Object.create(this);
line.x1 = x1;
line.y1 = y1;
line.x2 = x2;
line.y2 = y2;
return line;
}
};
Now you can draw your the above line by simply calling line.draw or else you could create a new line from it:
var line2 = line.create(0, 0, 0, 100);
var line3 = line.create(0, 100, 100, 100);
var line4 = line.create(100, 100, 100, 0);
var line5 = line.create(100, 0, 0, 0);
line2.draw();
line3.draw();
line4.draw();
line5.draw();
The lines line2, line3, line4 and line5 form a 100x100 square when drawn.
Conclusion
So you see you really don't need classes in JavaScript. Objects are enough. Encapsulation can be easily achieved using functions.
That being said you can't have public functions of each instance access the private state of the object without each instance having its own set of public functions.
This is not a problem however because:
You don't really need private state. You may think that you do, but you really don't.
If you really want to make a variable private then as ThiefMaster mentioned just prefix the variable name with an underscore and tell your users not to mess with it.
Aight, here's my attempt at solving this particular issue, although I think following conventions it's a better approach, ie. prefix your variables with _. Here I just keep track of the instances in an array, they can then be removed with a _destroy method. I'm sure this can be improved but hopefully it will give you some ideas:
var Class = (function ClassModule() {
var private = []; // array of objects of private variables
function Class(value) {
this._init();
this._set('value', value);
}
Class.prototype = {
// create new instance
_init: function() {
this.instance = private.length;
private.push({ instance: this.instance });
},
// get private variable
_get: function(prop) {
return private[this.instance][prop];
},
// set private variable
_set: function(prop, value) {
return private[this.instance][prop] = value;
},
// remove private variables
_destroy: function() {
delete private[this.instance];
},
getValue: function() {
return this._get('value');
}
};
return Class;
}());
var a = new Class('foo');
var b = new Class('baz');
console.log(a.getValue()); //=> foo
console.log(b.getValue()); //=> baz
a._destroy();
console.log(b.getValue()); //=> baz
You don't need private/public at runtime. These are enforceable statically. Any project complex enough to enforce private properties are not used outside will have a build/pre-process step, which you can use
to verify the fact. Even languages with syntax for private/public have a way to access private at runtime.
As for defining class-based objects, the constructor+prototype you are using is the simplest and most efficient way. Any kind of additional wizardry will
be more complex and less performant.
Although you can cache prototype so you don't have to repeat ClassB.prototype. all the time:
//in node.js you can leave the wrapper function out
var ClassB = (function() {
var method = ClassB.prototype;
function ClassB( value ) {
this._value = value;
}
method.getValue = function() {
return this._value;
};
method.setValue = function( value ) {
this._value = value;
};
return ClassB;
})();
The above does not require any library and you can easily create a macro for it.
Also, in this case even a regex is enough to verify
that "private" properties are used correctly. Run /([a-zA-Z$_-][a-zA-Z0-9$_-]*)\._.+/g through the file and see that the first match
is always this. http://jsfiddle.net/7gumy/
It's impossible as far as I know without other instances influencing the value, so if it's a constant you're still good by wrapping it in a function like this:
(function( context ) {
'use strict';
var SOME_CONSTANT = 'Hello World';
var SomeObject = function() {};
SomeObject.prototype.sayHello = function() {
console.log(SOME_CONSTANT);
};
context.SomeObject = SomeObject;
})( this );
var someInstance = new SomeObject();
someInstance.sayHello();
The best you could do is annotate that a property shouldn't be touched by using an underscore like this._value instead of this.value.
Note that private functions are possible by hiding them in a function:
(function( context ) {
'use strict';
var SomeObject = function() {};
var getMessage = function() {
return 'Hello World';
};
SomeObject.prototype.sayHello = function() {
console.log(getMessage());
};
context.SomeObject = SomeObject;
})( this );
var someInstance = new SomeObject();
someInstance.sayHello();
Here is an example of 2 'Classes' extending and interacting with each other: http://jsfiddle.net/TV3H3/
If you really want private entities on a per instance basis, but still want to inherit your methods, you could use the following set-up:
var Bundle = (function(){
var local = {}, constructor = function(){
if ( this instanceof constructor ) {
local[(this.id = constructor.id++)] = {
data: 123
};
}
};
constructor.id = 0;
constructor.prototype.exampleMethod = function(){
return local[this.id].data;
}
return constructor;
})();
Now if you create a new Bundle, the data value is locked away inside:
var a = new Bundle(); console.log( a.exampleMethod() ); /// 123
However you now get into the debate as to whether you should truly have private values in JavaScript. As far as I've found it's always better for those that may need to extend your code—even yourself—to have open access to everything.
There are also hidden downsides to the above pattern, besides not being so readable, or being clunky to access "private" values. One fact is that every single instance of Bundle will retain a reference to the local object. This could mean—for example—if you created thousands of Bundles, and deleted all but one of them, the data held in local would not be garbage collected for all Bundles ever created. You'd have to include some deconstruction code to fix that... basically making things more complicated.
So I'd recommend dropping the idea of private entities / properties, whichever pattern you decide to go for... object-based or constructor. The benefit of JavaScript is that all these different approaches are possible—it's no-where-near as clear cut as class-based languages—which some could argue makes things confusing, but I like the freedom JavaScript lends towards being quick and expressive.
with regards this statement in your question:
For instance in a vector drawing application, the workspace will usually be empty at the beginning of the drawing : I cannot create a new "line" from an existing one. More generally, every situation where objects are being dynamically created require the use of classes.
You seem to be under the misunderstanding that objects in Javascript can only be made by cloning existing objects, which would backtrack to the problem of "okay but what about the very first object? that can't be made by cloning an existing object because there aren't any existing objects."
However you can make objects from scratch, and the syntax for that is as simple as var object = {}
I mean, that's the simplest possible object, an empty object. More useful of course would be an object with stuff in it:
var object = {
name: "Thing",
value: 0,
method: function() {
return true;
}
}
and so on, and now you're off to the races!
There are cleverer people than I answering this question, but I wanted to note one part in particular that you just edited in - the private variable part.
You can simulate this using closures; an awesome construct which allows a function to have it's own environment. You could do this:
var line = (function() {
var length = 0;
return {
setLen : function (newLen) {
length = newLen;
},
getLen : function () {
return length;
}
};
}());
This will set line to be an object with the setLen and getLen methods, but you'll have no way of manually accessing length without using those methods.
I'd like to start by saying that I understand that JavaScript is a Classless language. My background is in Java, C++, and Objective-C which are all classic OOP languages that support Classes.
I'm expanding into Web Development and have been experimenting with JavaScript and learning its Patterns. Right now I'm working with the Constructor Pattern that simulates Classes with in JavaScript.
So this is my "practice" class:
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
var privateVarTest = 10;
this.getPrivateVarTest = function() {
return privateVarTest;
}
this.setPrivateVarTest = function( value ) {
privateVarTest = value;
}
}
Car.prototype.toString = function() {
return this.model + " is a " + this.year + " model and has " +
this.miles + " miles.";
}
var myCar = new Car( "Ford Focus", "2006", "65,000" );
document.getElementById('notepad').innerHTML += '</br> Testing </br>';
document.getElementById('notepad').innerHTML += myCar.toString() + '</br>';
document.getElementById('notepad').innerHTML += myCar.model + '</br>';
document.getElementById('notepad').innerHTML += myCar.getPrivateVarTest() + '</br>';
myCar.setPrivateVarTest( 20 );
document.getElementById('notepad').innerHTML += myCar.getPrivateVarTest() + '</br>';
Now I like using the prototype way of defining functions, as it doesn't instantiate a new version of the function for each Car Object created. However, in classic OOP languages we make our variables private and create public functions/methods to set and get these variables as needed.
JavaScript being Classless there is no private or public key word for this use, so I thought I'd experiment with a method of "faking" a private variable, and that's when found that using var instead of this essential makes it unaccessible out side of the constructor, but I was able to define getters and setters that would allow me to.
Now finaly to my question, sorry about the long wind up. For Best Practices from experinced JavaScript programmers, would you make all variables private to follow the standards of other OOP languages, and set getters and setter (which can not be prototyped forcing a creation for each Object), or avoid them as much as possible since the this keyword basicly lets you get and set all you want, and ONLY use private for hard coding some internal data needed for the class?
Thank you for taking the time to read this and providing to the discussion, I'm really just trying to get a feel for the standards that are used as Best Practices by experinced Web Developers.
General OOP
I'm in the camp that getters and setters are largely completely pointless and silly regardless of what language you're writing code in.
For the most part, exposed properties should be rare since any property of an object should typically be within the object's domain so only the object should actually change its own internals as a side-effect of other actions, not because some other object directly told it to change something. There are exceptions I'm sure (there always are) but I can't remember the last time I needed to make one.
Furthermore, when properties are exposed, the only reason to expose with a method is because you either can't just expose the property due to language constraints (Java) or because some validation or notification has to happen when you change that property. Just tacking on methods Java-bean-style that do nothing more than actually alter or return properties does nothing to preserve encapsulation. You might as well just make the property public if you can.
But the real problem with wanting to get/set everything willy-nilly from all over the place is that you've basically just written chained procedural code and called it OOP. You still have a long winding series of things that can only be reasoned about in terms of one happening after the other. With OOP, the idea is to avoid that long winding spaghetti chain so you can view your architecture more from the perspective of larger constructs that own specific domains interacting with each other at key points. Without that, you're perhaps reducing the spaghetti a touch by at least categorizing your functions under namespaces so it's easier to know where to look for stuff but you're not really leveraging the key wins that OOP can provide your architecture.
The real value of private or in JS's case local constructor/factory-closur vars is signalling intent. If it's exposed, something external really should be changing it. If it isn't, then you've made it clear that the var is only the object's business.
JS OOP
My advice is to forget class-emulation in JS. It's completely unnecessary. Prototypes are elegant and easy once you understand them. Think of a constructor's prototype property as a kind of a backup object. If you call a method on an instance that it doesn't have, the next step is to check the instance's constructor's prototype object property. If that object doesn't have it, then its constructor's prototype object gets checked and so on until you finally reach the core Object constructor's prototype.
It's because of that lookup process that you can add new methods to a constructor on the fly and have all instances "inherit" it after they've been built but it's not really inheritance so much as a fallback process.
Inheritance in JS is stupid-easy. That doesn't mean you should do a ton of it though. Long chains of cascading inheritance is regarded as an anti-pattern in any language for good reason and due to the way the callback process works, it can also really kill perf if you're hammering on the call object through like 18 levels of prototypes for every little thing in JS. I would say prefer composite objects to inheritance and when inheritances seems like a wiser option, check yourself any time you're tempted to inherit through more than 2-3 prototype links in the chain.
Oh, and one JS gotcha to look out for on local instance vars in the constructors as private properties: that's just JS's closure rules within a function scope context in action really. Methods declared in the prototype or outside of the constructor function can't access those internal vars. Constructor functions invoked with the new keyword change the rules of what 'this' accesses and they leave an instance behind but are otherwise executed JS functions in every other way.
Other flavors of crazy but also crazy-powerful worth understanding in JS OOP are the apply, call, and now bind methods. I tend to see these more as things you'd want in a factory but they are very powerful.
Once you've mastered JS OOP, start understanding JS from a functional perspective and you'll discover it has a really powerful 1-2 punch combo going on. We can do just about anything very easily and with a minimum of code in JS. The design tradeoff is performance (which modern JIT compilers are handling surprisingly well) and that it gives you plenty of rope to hang yourself with. I prefer the rope. The self-lynching is no fun but that's part of the learning/developing better instincts process which happens much faster as a result and leads to more maintainable code in the long haul. Whereas Java basically forces OOP implementation but due to being overly protectionist in regards to devs doing dumb things to themselves, results in community wide adoption of practices that run completely counter to the whole point of OOP.
The short version:
Stop getting/setting a lot if you do, regardless of language. It drastically reduces the win factor of implementing OOP in the first place.
Prototypes are really simple, elegant, and powerful. Tinker with them. Learn them. But be warned. Classes might start to feel archaic, clumsy, and overwrought in comparison (although to be fair, completely necessary in non-interpreted languages).
To make JS work well for you, self-learn the crap out of whatever aspect of it you happen to be dealing with. The rewards in terms of raw elegant linguistic power are more than worth the time spent. JS is closer to Scheme than the languages you listed being familiar with so it's weird but it's not being weird arbitrarily or without design principles in mind and JS's dominating success in web UI is no accident, regardless of what people telling everybody we're "stuck with it" would have you believe.
Full disclosure: I don't love Java.
Update:
The es6 class keyword changes virtually nothing about OOP in JS. It's 100% syntax-sugar. IMO, the use of the word "class" isn't doing newcomers any favors but there are advantages/disadvantages to all three styles of object constructor/creation and object instantiation in JS and they're all worth knowing/understanding. Those three approaches are functions as constructors, Object.create, and now the class keyword.
We need to be aware of our tendency to want every new language we learn to behave identically to the last language we learned. Or the first. And so forth. Douglas Crockford has a great (albeit a bit dated) google talk, in which he muses, "Javascript is the only language I know of that people feel they don't need to learn before using it". That talk will answer a lot of questions you never knew you had, including the one you've asked here.
There's nothing wrong with writing setters and getters. There's rarely harm in doing work to keep one's own sanity. You will happen to have a 'C accent' when speaking JS, but at least you'll be clear in your intent to anyone reading your code.
My sanity saving tip for managing 'this' across scopes, always remember that you can save your current 'this' before entering a new context:
var self = this;
I avoid using prototype except in special cases by including my object methods within the scope of the declaration.
function MyClass(_arg){
var self = this;
this.arg = _arg;
this.returnArg = function(){
return self.arg;
}
}
var foo = new MyClass("bar");
foo.returnArg(); //"bar"
in case of OOP I have to say infact javascript provide some level of oop.
by that I mean 4 main concepts of OOP design could be implemented in javascript although it is not strong and very well defined as in Java or C++. lets check those concepts and I will try to provide an example for each of them.
1- Abstraction : here as I said before we can understand why OOP is not very well defined as in Java, in Java we implement Abstraction concept using Classes, Variables, interfaced,... but in javascript Abstraction is rather implicitly defined in contrast to other OOP languages such as Java.
2- Encapsulation : I guess an example will suffice here
function Student (stdName, stdEmail, stdAvg) {
this.name = theName;
this.email = theEmail;
this.avg = stdAvg;
}
here also as you see we define a "class" like concept using functions in fact if get type Student you'll see it is a function.
3,4 - Inheritance and Polymorphism :
the way that JavaScript achieves Inheritance and Polymorphism is different than Java or C++ because of its prototypial (to be honest I have no idea any other way to say that) approach.
const Gun = function(soundEffect){
this.soundEffect = soundEffect;
};
Gun.prototype.fire = function(){
console.log(this.soundEffect);
};
const DesertEagle = function(color,clipSize){
this.color = color;
this.clipSize = clipSize;
};
DesertEagle.prototype = new Gun("pew pew peeeew");
const myWeapon = new DesertEagle("black",15);
myWeapon.fire();
now in order to cover the public/private access for variables and functions we have to use some kind of technique to implement such concept. check the code below:
const Student = function(name, stdNumber, avg){
this.name = name;
this.stdNumber = stdNumber;
this.avg = avg;
var that = this; //NOTE : we need to store a reference to "this" in order for further calls to private members
this.publicAccess = { // a set of functions and variables that we want as public
describe: function () {
console.log(that.name + " : " + that.stdNumber);
},
avg: this.avg,
};
return this.publicAccess; // return set of public access members
};
const newStd = new Student("john", "123", "3.4");
newStd.describe();
// output: john : 123
console.log(newStd.avg)
// output: 3.4
in ES6 defining a class is mush easier but it is just syntax sugar it is still the same thing at the heart of it.
I hope it will help .
I also recommend you this article (Javascript design patterns) it will provide some helpful information about avascript capabilities and design patterns.
please accept my apology for my poor English.
Coming from mootools and JAVA, mootools class implementation is a real nice way to structure my code, plus I can have some nice features like extending, implementing and so on. Starting with jquery I found my self writing $.fn plugins that cant use code of other plugins. Plus it seems no good idea to use the plugin structure for complex stuff that hasn't much to do with DOM Elements. Is there a better way then $.fn? What do you recommend to structure my code using jquery.
This is a tough question to answer.
JavaScript's incredible flexibility's downside is that every programmer and his brother-in-law has a different way of doing things.
The downside of pulling in a library for doing "Class" based OOP in JavaScript (Prototype library, Moo, Joose, JS.Class, Base2, etc.) is that you immediately cut down on the number of fellow JavaScript programmers who can read your code.
Obviously, jQuery encourages you to think in terms of "collections." A collection is what you get back from a $() or jQuery() call. John Resig once considered adding a class system to jQuery, but finally decided against it. I think he's said that he's never needed a real "Class" system in JavaScript programming.
For all but the largest JS projects, I'd say forget about a Class system. Leverage JS's incredible object and array system (including literals). Namespace heavily (variables and methods alike).
I've had a lot of luck using arrays of objects for most situations I'd normally use Classes for.
An interesting extension of the jQuery collection concept is in Ariel Flesler's jQuery.Collection plugin here. It lets you treat "normal" data much as you would treat DOM data in jQuery.
I recently started using Underscore.js, which gives you a lot of functional tools to treat your data as collections.
What you generally need are mechanism for code extension and packaging.
For the former, I use the pseudo class-based default oo mechanism, sometimes with a helper function to make inheritance easier:
Function.prototype.derive = (function() {
function Dummy() {}
return function() {
Dummy.prototype = this.prototype;
return new Dummy;
};
})();
function Base() {}
function Sub() {}
Sub.prototype = Base.derive();
The latter can be achieved by namespacing via self-executing functions. It's even possible to fake import statements:
// create package:
var foo = new (function() {
// define package variables:
this.bar = 'baz';
this.spam = 'eggs';
// export package variables:
this.exports = (function(name, obj) {
var acc = [];
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
acc.push(prop + '=' + name + '.' + prop);
}
return 'var ' + acc.join(',') + ';';
})('foo', this);
});
// use package:
(function() {
// import package variables:
eval(foo.exports);
alert(spam);
})();
jQuery isn't really meant to be used for structuring your code. It's meant to be a tool that you use from your other code, not a way of life.
The rest of your code should be written whatever way you like. Just use jQuery when you want to do DOM manipulation, Ajax calls, cross-browser events, etc.
You may want to learn how to use the .prototype property to put some of your code into "classes", so that you can reuse the same code in different places, by just creating a new instantiation, basically.
You can also put code into objects so that you have a unique namespace, so it is easier to share related objects amongst different projects.
Basically you will be structuring your code as you do for straight javascript, but jQuery abstracts out some of the common functionality so you don't have to worry about browser issues, but it is just a helper, it really doesn't provide a framework as much as just making some concepts simpler. For example, rather than using onclick I tend to use .bind('click', ...) but that is if I want to have the potential of more than one event hander on an element.