The following answer to this question does a great job explaining the differences between classical inheritance and prototypal inheritance. this was of interest to me to understand because I started working in Java, but moved over to Javascript.
In his answer, he states for prototypal inheritance that, "All of the business about classes goes away. If you want an object, you just write an object."
Yet there is so much documentation and questions on how to "write classes" in Javascript.
Why is there push to make the language something it is not. I'm looking for concrete examples of cases where using classes in JS applications are more sensible in this prototypal language and the benefits of awkwardly fitting a square peg into a round hole. As Aravind put it, why are people learning Javascript by comparing it to others, and not as it was intended... and why is this practice seemingly encouraged?
Bottomline question: Why are classes being introduced in ECMAScript 6?
The masses like classes.
There's nothing "more" or "less" natural about prototypal inheritance, this is entirely subjective. JS is its own language, just like Smalltalk and Self had different ideas about what it meant to be an object.
ES6 classes are syntactic sugar. They normalize/clean up how inheritance/etc are to be used in JS.
Similar to CoffeeScript, they attempt to standardize how OOP is done in JS, and make it more familiar to people that aren't used to prototypal inheritance.
Why are people learning Javascript by comparing it to others, and not
as it was intended?
This gets into cognitive and learning theory, but the short version is that humans like things that are familiar, and one of the ways we learn is by relating new ideas to knowledge we already have.
Why are classes being introduced in ECMAScript 6?
Classes were almost introduced in ECMAScript 4, actually. I think there are good arguments for OOP being a useful pattern for writing complex software, and class based inheritance is more familiar to many programmers than is prototype based inheritance. I think an equally valid question might be "why does JavaScript still implement prototype based inheritance when most people who learn it will be more comfortable with class based inheritance?"
If you're curious what classes in JavaSCript might look like, take a look at ActionScript 3, which is based on that draft of EMCAScript 4 with class based inheritance.
Of course, just because ECMAScript adds class support does not mean that JavaScript will, or at least that it will any time soon.
I found this article by Zakas explaining it clearly, that it's just syntactic sugar, and at the end of the day Javascript will work the same way.
Don't worry about having to learn classes or having to shift your programming styles, nothing changes. :)
Why are classes being introduced in ES6? Sugar, of the syntactic variety.
Classes are very good for people who come to JavaScript from object-oriented languages (like Java).
This is the experience I've made several times already. I had a number of J2EE web projects with good Java dev teams, who had some JavaScript knowledge, but not much. Almost the first thing I did was to explain prototypes, prototypal inheritance and how one can implement the OOP paradigm using prototypes - basically the pseudoclassical inheritance. (Now I routinely do a "JavaScript for Java Developers" workshop almost in every project of that kind.)
With that approach I mostly saw good code coming out. Most Java developers tend to stick to the pseudoclassical pattern and are quite happy with it. This is most probably not what JS ninjas out there would write, but, frankly, I don't care. The code is easy to understand and to maintain, people had a good learning curve and were productive very fast.
Prototype languages, like JavaScript, are really great for small scale, short term projects that don't require a lot of testing or maintenance. Their simple and flexible functionality really shines in this realm.
Class based languages on the other hand tend to be a little more rigid and require more setup, which isn't as great at the little stuff but the extra structure is helpful to keep the larger, long term projects scalable and manageable.
When JavaScript first started, its primary function was to manipulate static DOM elements, which is a great application for a prototype language. Fast, flexible and simple -- no fuss. Now, however, the role that JavaScript fills is much more complex and is more and more an application than a simple script. Adding classes to a prototype language does sound a little funny, but the added structure classes provide, along with their widespread familiarity could very easily help teams of developers handle the complexity of modern JavaScript applications.
Related
There are lots of articles and posts explaining how JavaScript inheritance works, but why was JavaScript implemented using prototypal inheritance instead of classical inheritance?
I love JavaScript, so I'm not saying it's bad thing... I'm just curious.
Here's what Brendan Eich has to say about what happened:
https://brendaneich.com/2008/04/popularity/
As I've often said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of "doing Scheme" in the browser. At least client engineering management including Tom Paquin, Michael Toy, and Rick Schell, along with some guy named Marc Andreessen, were convinced that Netscape should embed a programming language, in source form, in HTML.
The diktat from upper engineering management was that the language must "look like Java". That ruled out Perl, Python, and Tcl, along with Scheme.
I'm not proud, but I'm happy that I chose Scheme-ish first-class functions and Self-ish (albeit singular) prototypes as the main ingredients. The Java influences, especially y2k Date bugs but also the primitive vs. object distinction (e.g., string vs. String), were unfortunate.
JavaScript was originally supposed to be very much like Lisp. Even after the syntax was changed to more closely resemble C/Java, it is still Lisp in C's clothing. I think the answer lies in it's functional programming origins. In pure FP, there is no mutable state, which means no mutable objects. If you relax the rules a bit and get slightly creative, you end up with something like protypal inheritance, i.e., you can extend objects but not modify the original object. It provides the same power as inheritance and still gives you some immutability.
Finally, twist the language around to make it look like C++ and Java, and viola, you have new someFunction() and the rest is history.
Because it was heavily influenced by Self. Both Wikipedia and the ECMA-spec mention this.
I think it was chosen because it is easy to implement, needs no extra keywords and users don't need to understand it to be able to use the language. It is also more powerfull and flexible than class based inheritance.
It's a natural choice for a untyped language. The main advantages of class based inheritance are that it allows static typing and thus type checking and a faster table based lookup implementation.
Prototypical inheritance (with closures) allows others to do things that were never envisioned. It's the meshing of several paradigms that have come together to achieve general purpose programming.
With a prototype language, you can have "mix-ins" for your classes. You can accomplish the level of encapsulation you desire, without language specific keywords. In short, prototype languages are awesome.
I hate to say it, but JavaScript, plus some libraries, can do everything I need it to. It was subversive in its development (supposed to be subservient to Java). It has much power, in the simplest of implementations.
With enough study / playing around, you'll begin to see the advantages of it's inspiration. JavaScript is one of the few languages that "hid" it's potential intentionally. You gotta get into the politics if you want to know the "why." But, it's for this reason, that it's awesome.
ECMAScript 5 is in final draft now, and includes new features relating to objects and prototypes. While hunting around SO and Google for OOP design patterns, I found that there were quite a few different ways of "doing OOP" (however you might define OOP, from trying to emulate classical OOP to simply trying to cut down namespace pollution) in JavaScript.
Which design pattern is the most forward-looking vis-à-vis the direction ECMAScript 5 is taking the JavaScript world? What are its key advantages? Which of those weren't possible or as nice to implement before?
I don't think ECMAScript 5 changes the landscape for OOP in JavaScript. Classical OOP will still be a bolt-on for people who want to use it.
The real story, in my opinion, is that when ECMAScript 4 was scrapped, JavaScript and ActionScript diverged, and JavaScript will NOT be adding classes the way ActionScript did.
I suspect that the libraries that support OOP (MooTools, Prototype, etc.) will mostly stick to what they are doing, but maybe they can use some new ECMAScript 5 features in their implementations to solidify things.
And we'll probably keep seeing interesting approaches like Joose and Class.js.
Remember this is going to take awhile. We still have a double-digit chunk of people using IE6. So the first useful places to use ECMAScript 5 will probably be on mobile phones, Adobe AIR, and JavaScript servers, where the browser is (mostly or strictly) known.
John Resig posted an article on ECMAScript 5's object changes here.
I think the standardization of Object.create will allow more people to use the underlying prototype-based OO without shame. Trying to hide the "new Foo" pseudo-classical syntax behind a wrapper makes the code confusing.
We have a CMS built on Java and it has Mozilla Rhino for the server side JS. At the moment the JS code base is small but growing. Before it is too late and code has become a horrible mess I want to introduce some best practices and coding style.
Obviously the name space control is pretty important. But how about other best practices - especially for Java programmers?
Here's some tips from the front lines:
Like Java, use docblocks in Doxygen/JsDoc style for functions
Unit test. Personally like JsTestDriver, as it can be executed automatically from CI server too.
Use JSLint. It will nitpick about bad code
Consider using Google Closure Compiler. It will nitpick about code like JSLint, but it can be helpful for spotting poor doc blocks etc.
Make sure everyone on your team understands how closures work. Otherwise it'll lead to headaches
As you mention, namespaces are important especially if you want your code to work nice with other JS libraries (var myns = myns || {};)
Personally I find using a library which provides OOP helpers like classes etc. helpful. You could use prototypal inheritance but it's often a bit trickier that way.
As Douglas Crockford likes to say, JavaScript is the worlds most misunderstood programming language. Though many people don't know it, there is a right way to code in JavaScript. I have no doubt that if you let Java developers start coding before understanding how to write good JavaScript you will run into serious trouble.
The first thing to do would be to make sure everyone has read Mozilla's excellent article, A re-introduction to JavaScript (https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript). One of the biggest problems with JavaScript is that there are many ways to do most common tasks, and this article should get people on the same page. Another essential reference is Douglas Crockford's work, including JavaScript: The Good Parts.
One other thing that gets a lot of Java/C++ programmers is that JavaScript uses function scope NOT block scope. This can cause some very tricky problems. There's a great article about this issue at A List Apart called Binding in JavaScript.
To summarize the major issues talked about in the above resources, the most crucial differences to learn are
how to write object oriented code using prototypal inheritance (vs.class based inheritance)
how to use closures and lambdas
how to utilize the power of dynamic objects
how to write function-scoped code
Since you have a JS engine in Java, make it a habit to write unit tests for your JS code. Select a coding style and apply it vigorously. If possible, use tools to check that the code submits to the coding style.
I'm spending a lot of time to learn how OOP is implemented in Javascript as in ECMA 262 of 1999: now I want to know if someone think that the new JS 2.0 will arrive soon and I am
studying uselessly because with this new version will be the OOP implemented in a classical way (Java etc.) and will be interfaces, generics and other classical languages features...
So do I must stop and wait?
Javascript is a dynamically typed script language that uses prototype based inheritance.
It is exactly these attributes that differentiate it from Java, C# and make it so applicable for web development in particular. Why would anyone want or need to turn it into another Java or C#, they already do that job quite well.
So no, learning Javascript now is very worthwhile. Learning Javascript more deeply has actually helped me to better understand dynamic languages in general (coming from C#,C++) and even has some Functional aspects to get to grips with.
JavaScript 2 is dead. There'll be ECMAScript 3.1, which will feature mostly clarifications, security enhancements and library updates, and ECMAScript Harmony, the replacement for ECMAScript 4 (aka JavaScript 2). A lot of the things planned for ES4 are no longer under discussion for Harmony, though.
I would highly recommend you learn JavaScript as it is. Whatever changes may come, you'll still be forced to deal with the historic usages sooner or later, and probably very often if you are a web developer. I would also recommend Crockford's JavaScript: The Good Parts, as it covers all modes of inheritance and strips away the bad stuff you shouldn't use.
I think there's enough existing code out there in the current Javascript version that even if some new JS version were released today, it would still be worth learning how the current version works.
You should still learn how OOP works in current version of JavaScript (ECMAScript). ECMAScript 3.1 introduces a whole bunch of static Object functions, including inheritance.
Actually, you can already implement the Object.create() function in current JavaScript (code by Douglas Crockford):
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
// you can now do this
newObject = Object.create(oldObject);
Word of caution though, you don't need to use OOP all the time. If OOP makes sense then use it, if not don't.
Like Christoph said, JS2.0 is dead. Like Herms said, there is enough code out there that it is Definitely worth learning the current version. And JavaScript is a very easy-to-learn, quick way to learn about the basics of OOP in any language. You are not studying uselessly, and I applaud you for studying! I would recommend that you keep going.
Since the heavy hitters all do OOP in a similar fashion (Java, .Net, Python), I would guess than anything done would follow those similar methodologies. Since so much is done in those languages, there is a huge amount of training that has gone into cementing those processes in the collective mind, and at this point there doesn't seem to be much need to change things.
I am looking get to grips with functional programming concepts.
I've used Javascript for many years for client side scripting in web applications and apart from using prototypes it was all simple DOM manipulation, input validation etc.
Of late, I have often read that Javascript is one of the languages that supports functional programming.
With my familiarity and experience with Javascript, my preference is to use it to learn functional programming. I expect I would be able to concentrate more on the main functional concepts and not get bogged down or distracted by a completely new syntax.
So in summary, is Javascript a good choice to learn functional programming concepts? What capabilities in Javascript are relevant/support functional programming?
JavaScript supports first class functions. See Use functional programming techniques to write elegant JavaScript.
Higher Order Javascript is a great way to get familiar with the functional aspects of javascript. It's also a relatively short read in case you want to get your feet wet without diving into a larger book.
I would say that although you can quickly grasp some functional programming concepts with JavaScript, using JavaScript consistently like a functional programming language is not a common practice. At least not obviously common. Most people don't post tutorials that pinpoint how to do functional programming with JavaScript -- the one marxidad pointed out is actually a pretty decent example, but you won't find a lot of that. The functional aspects are not often apparent, just like when people use closures in JavaScript, but are unaware that they are doing it.
The idea that you would pass two functions through as arguments to a third function, and then have the return value be some execution related to the first two functions is an advanced technique that almost always appears only in the core of full-blown libraries like jQuery. Self executing anonymous functions and the like have gained ground, but are still not used consistently. The majority of tutorials often focus instead on JavaScript's OO capabilities, like how to create properties and methods, scope, access control and also how to use the prototype property of constructors. Honestly, if functional programming is what you want, then I would choose a language known strictly for this capability.
I don't remember who said it, but javascript has been called "Scheme with Algol syntax". So for learning Scheme/Lisp, Javascript isn't a bad start. Note though that functional languages like Lisp are quite different from pure functional languages, such as Haskell.
Apart from "first-class functions" (Meaning that functions are values, that can be assigned to variables), lexical scope is also an inherent part of what makes a functional language.
Higher Order Javascript and The Little Javascripter has been mentioned already. They are both excellent texts. In addition, Higher Order Programming in Javascript may be an easier start.
Although javascript supports FP to some degree, it does not directly encourage it. That's why projects like Oliver Steele's Functional exist, to fill in the gaps. So I wouldn't recommend it for learning FP. Check out F# instead.
I would recommend reading The Little Schemer, which is a fairly slim book about recursion and is a good introduction to the functional style. Whilst it's focused on Scheme it can easily be applied to JavaScript, see http://javascript.crockford.com/little.html. I found it really helpful in my javascript development, although it gets quite tricky towards the end.
Javascript is a multi-paradigm language. If your goal is to learn functional language concepts, try starting with a pure functional language like OCaml or Haskell.
Also, Eloquent JavaScript: Functional Programming chapter.