Object-oriented JavaScript for C# Developers
The Mastering the Arcane Art of JavaScript-mancy series are my humble attempt at bringing my love for JavaScript to all other C# developers that haven’t yet discovered how awesome this language and its whole ecosystem are. These articles are excerpts of the super duper awesome JavaScript-Mancy book a compendium of all things JavaScript for C# developers.
Through the last couple of years I have been working on improving my JavaScript-Fu. From looking down at JavaScript with contempt, I have come to love the language and its little idiosyncrasies. In this article, I will attempt to write the article I would have loved to read, the first time I set my mind to re-learn JavaScript the proper way.
Ey You C# developer! Wanting to learn you some JavaScript? You’ve come to the right place! In this article you will learn how to map all those OOP C# concepts you have come to know and love to JavaScript, the ever growing language of the web! I will help you traverse the waters of Object-oriented programming by going through the pillars of OOP (encapsulation, inheritance and polymorphism) and trying to work out how they can be achieved in JavaScript.
Note: In this article I will use two types of code samples. Some that you can type in a text editor, and others that you can run directly in any JavaScript REPL (in the Chrome Dev Tools console for instance). In these second type of examples every line will be preceded by a >
followed by the result of evaluating an statement, and that’s how you will be able to differentiate them. I recommend the Chrome Dev Tools REPL (Console) because it will let you copy/paste even the first type - biggish - code examples on the REPL.
Encapsulation
Encapsulation is the packing of data and functions into a single component.
The easiest way to achieve encapsulation in JavaScript is by using object literals:
var conan = {
name: 'Conan, The Barbarian',
'character class': 'barbarian',
hp: 200,
weapons: [
{
name: 'two-handed sword',
type: 'sword',
damage: '2d20+10',
material: 'cimmerian steel',
status: 'well maintained',
equipped: true,
},
],
talk: function() {
console.log('I am ' + this.name + ' !!!')
},
}
This will look familiar to you since we also have object literals in C#:
var conan = new Barbarian
{
Name = "Conan, The Barbarian",
CharacterClass = "barbarian",
Hp = 200,
Weapons = new List<Weapon>
{
new Weapon {
Name = "Two-handed sword",
Type = "sword",
...
}
}
};
// Somewhere else we have the class definition
public class Barbarian{
public string Name {get; set;}
public string CharacterClass {get; set;}
...
}
However if you look closely at the JavaScript example you will notice that there’s no class identifier. What!? Welcome to the Jungle! There are no classes in JavaScript! (Although that may not hold true soon enough…).
An object literal in JavaScript is an easy way to create a single instance of an object with whichever arbitrary properties that you desire. All object literals and (all objects in JavaScript for that matter) are instances of the base Object
type.
> var conan = {
name: "conan"
};
undefined
> conan instanceof Object
true
Ok, so what happens if you want to create multiple similar objects? Do you need to instantiate them via literal objects one at a time? Nope, JavaScript provides Constructor Functions for just this purpose.
Constructor Functions
Constructor functions are JavaScript functions that allow us to create multiple instances which share the same properties. They work as a recipe for object creation and they represent a custom type (yep, this starts feeling like a class). Let’s see an example!:
function Barbarian(name) {
this.name = name
this['character class'] = 'barbarian'
this.hp = 200
this.weapons = []
this.talk = function() {
console.log('I am ' + this.name + ' !!!')
}
this.equipWeapon = function(weapon) {
weapon.equipped = true
this.weapons.push(weapon)
}
}
Notice how the constructor, not only initializes an object with a set of values like in C#, but it also determines which properties an object is going to have. Effectively it works both as a constructor and a class definition (if we were to draw a parallelism with C#).
To create a new instance of a Barbarian
we use the new
keyword just like in C#:
var conan = new Barbarian('Conan, the Barbarian')
conan.equipWeapon({
name: 'two-handed sword',
type: 'sword',
damage: '2d20+10',
material: 'cimmerian steel',
status: 'well maintained',
})
This new instance is of type Barbarian
and all its properties are publicly available:
> var conan = new Barbarian("Conan, the Barbarian");
undefined
> conan instanceof Barbarian
true
> conan instanceof Object
true
> conan.talk();
I am Conan, the Barbarian!!!
> conan.name;
"Conan, The Barbarian"
> conan.weapons;
[]
Data/Information Hiding
Information hiding is the principle of segregation of the design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed.
In the previous function constructor example we saw how all properties that we defined in the constructor function where publicly available. We may not want to have all our object implementation details out in the open, right? How do we then achieve private properties in JavaScript? We take advantage of closures, functions that refer to free variables from an outer scope.
We have closures in C# so I will not delve a lot on them but for this teeny tiny example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var Add5 = AddX(5);
var number = 0;
Console.WriteLine(string.Format("Initial Number: {0}", number)); // Initial Number: 0
number = Add5(number);
Console.WriteLine(string.Format("Add 5 and it becomes: {0}", number)); // Add 5 and it becomes: 5
number = Add5(number);
Console.WriteLine(string.Format("Add 5 and it becomes: {0}", number)); // Add 5 and it becomes: 10
var Add100 = AddX(100);
number = Add100(number);
Console.WriteLine(string.Format("Add 100 and it becomes: {0}", number)); // Add 100 and it becomes: 110
}
/// <summary>
/// A function that creates another function that adds a given number X to another number
///
/// The returned function is a closure over the free variable 'x'. As you can see in the
/// example above, the created function retains the value of the variable it encloses.
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static Func<int, int> AddX(int x)
{
return number => number + x;
}
}
}
In JavaScript we can create a closure like this:
function Barbarian(name) {
// this variables are only available in the scope
// of this function.
// Remember, in JavaScript, only functions create new scopes!
var weapons = [],
characterClass = 'barbarian',
hp = 200
this.name = name
this.talk = function() {
console.log('I am ' + this.name + ' !!!')
}
this.equipWeapon = function(weapon) {
weapon.equipped = true
// Now we reference the weapons variable directly
// creating a closure.
// You cannot use this.weapons to access this variable any more
// It is so private that the only way to access it is via closure
weapons.push(weapon)
}
}
Which makes the weapons
, characterClass
and hp
variables effectively private: They are no longer accessible from the outside.
> var conan = new Barbarian("conan");
undefined
> conan.name;
"conan"
> conan.weapons;
undefined
Method Overloading
There is no such thing as method overloading in JavaScript, or at least method overloading as we know it in C#. If you define a method within an object twice, the second method will overwrite the first (ups!):
> var barbarian = {
sayHi: function(){console.log("hi!";)},
sayHi: function(){console.log("WaaaaZaaaa!");}
}
undefined
> barbarian.sayHi();
"WaaaaZaaaa!"
In fact, you can call any function with any number of arguments and JavaScript will just run with it:
> var barbarian = {
sayHi: function(){console.log("hi!";)},
sayHi: function(message, message2){console.log("hi! " + message + ", " + message2);}
}
undefined
> barbarian.sayHi();
"hi! undefined, undefined"
> barbarian.sayHi("I am Groot!");
"hi! I am Groot!, undefined"
> barbarian.sayHi("I am Groot!", "Waaaaa....")
"hi! I am Groot!, Waaaaa...."
How do we then provide support for method overloading in JavaScript? Well, we handle it in kind of a rudimentary way. Every function scope in JavaScript has a special variable called arguments
, which behaves sort of like an array, but it is not an array, which contains all arguments passed to the function, and which can be used in the fashion below to mimic method overloading:
> var barbarian = {
sayHi: function(){
var args;
if (arguments.length === 0) {
console.log("hi!");
}
if (arguments.length === 1){
console.log(arguments[0]);
}
if (arguments.length > 1){
// this is like type casting the arguments array-like variable
// to an actual array so that I can use the join method
args = Array.prototype.slice.call(arguments);
console.log("hi " + args.join(", "));
}
}
}
undefined
> barbarian.sayHi();
hi!
> barbarian.sayHi("I am Groot!");
I am Groot!
> barbarian.sayHi("I am Groot!", "Waaaaa....", "For Great Justice!")
hi! I am Groot!, Waaaaa...., For Great Justice!
- Fun Fact: the
length
property of any function returns the number of arguments it expects (its arity). Isn’t that unexpected? XD
Object Augmentation
An interesting feature of JavaScript is that you can add or remove properties from objects at any point in time. This enables interesting object composition patterns like mixins.
You can add new properties to any object by using the .
notation:
> var conan = { name : "conan"};
undefined
> conan.title = "the barbarian";
undefined
> conan.title
the barbarian
> conan.sayHi = function(){console.log("HI! I am " + this.name + ", " + this.title)};
undefined
> conan.sayHi()
Hi! I am conan, the barbarian
And remove properties by using the delete
keyword:
> var conan = { name : "conan"};
undefined
> conan.name
conan
> delete conan.name
true // delete always returns true
> conan.name
undefined
Inheritance
In object-oriented programming (OOP), inheritance is when an object or class is based on another object or class, using the same implementation (inheriting from a class) or specifying implementation to maintain the same behavior (realizing an interface; inheriting behavior). It is a mechanism for code reuse and to allow independent extensions of the original software via public classes and interfaces.
[Inheritance](http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming) in JavaScript is slightly different than what we are accostumed to in C#. For one, there are no classes (ouch!), furthermore, inheritance doesn’t play as big a part in polymorphism since JavaScript is a dynamically typed language that relies in duck typing instead (as we will see in the next section). JavaScript is all about objects, and achieves inheritance not via class inheritance but via prototypical inheritance, that is, objects that inherit from other objects which act as prototypes (a sort of blueprint).
Prototypes
Every function in javascript has a prototype
property that holds an object that will act as a prototype - will provide shared properties - for all objects created via that function and the new
keyword. The prototype
object has in its turn a constructor
property that points back to the constructor function:
> function Barbarian(name) { this.name = name; }
undefined
> Barbarian.prototype
Barbarian {}
> Barbarian.prototype.constructor
function Barbarian(name) { this.name = name; }
> Barbarian.prototype = {}
undefined
> Barbarian.prototype
In the simplest inheritance scenario, you can create an inheritance hierarchy by setting the prototype
property of a constructor
function. By doing that, all objects instantiated using that constructor
function will inherit properties and methods from the prototype
object:
> function Barbarian(name){ this.name = name; }
undefined
> Barbarian.prototype.sayHi = function (){ console.log("Hi! I am " + this.name);}
undefined
> var krull = new Barbarian("krull");
undefined
> krull.sayHi()
Hi! I am krull
In a more common scenario you may have several custom prototypes in your inheritance hierarchy:
// Inheritance Hierarchy:
// Barbarian -> DrawableGameObject -> GameObject -> Object
function GameObject() {
// game object ctor
}
function DrawableGameObject() {
// drawable object ctor
}
DrawableGameObject.prototype = Object.create(GameObject.prototype)
DrawableGameObject.constructor = DrawableGameObject
function Barbarian() {
// barbarian ctor
}
Barbarian.prototype = Object.create(DrawableGameObject.prototype)
Barbarian.prototype.constructor = Barbarian
// copy paste code from the example of the Chrome Dev Tools console
> var conan = new Barbarian();
undefined
> conan instanceof Barbarian
true
> conan instanceof DrawableGameObject
true
> conan instanceof GameObject
true
It is important to note that each property defined in the constructor
function will be part of every single object instance, whilst each property defined in the prototype
will be shared amongst all object instances. Again:
constructor
properties and methods are defined in each instanceprototype
properties and methods are only defined in the prototype. This emulatesstatic
variablesproperties. Methods can still refer to a particular instance by using thethis
keyword.
A common idiom to avoid needing to write the Function.prototype.property
each time you want to update the prototype is to assign the prototype to a new object:
> function Barbarian(name){ this.name = name; }
undefined
> Barbarian.prototype = {
constructor: Barbarian
sayHi: function(){console.log("Hi! I am " + this.name);}
}
undefined
> var conan = new Barbarian("conan");
undefined
> conan.sayHi()
Hi! I am conan
> conan instanceof Barbarian
true
In summary once more, because this was weird as hell the first time I saw it, to emulate a C# class you would need to create a constructor
function that will contain the specific properties of each particular instance and a prototype
that will provide a series of shared methods and static members that will be shared across of all instances of a given type.
The Prototype Chain
When we use prototype inheritance as a method of code reuse, to reduce duplication and optimize memory, a prototype chain is built between object and the different prototypes in the inheritance hierarchy. When we call a method on a particular object instance, the JavaScript runtime tries to find that method in the object itself and if it can’t find it, it follows the prototype chain until it does:
> function Barbarian(name){this.name = name;}
undefined
> Barbarian.prototype.ravage = function(){console.log(this.name + "attaaaaack!!");}
undefined
> var conan = new Barbarian("conan");
undefined
> conan isintanceof Barbarian
true
> Barbarian.prototype.isPrototypeOf(conan)
true
> conan.ravage === Barbarian.prototype.ravage
true
> conan isintanceof Object
true
> Object.prototype.isPrototypeOf(conan)
true
> conan.toString === Object.prototype.toString
true
In the example above, we can appreciate how within the conan
object instance, the ravage
method is part of the Barbarian.prototype
and the toString
method is part of the Object.prototype
.
Differentiating Between Object Properties and Prototype Properties
In order to know whether a property is part of the object itself or part of the prototype you can use the hasOwnProperty
method:
> function Barbarian(name){this.name = name;}
undefined
> Barbarian.prototype.ravage = function(){console.log(this.name + "attaaaaack!!");}
undefined
> var conan = new Barbarian("conan");
undefined
> conan.hasOwnProperty("name")
true
> conan.hasOwnProperty("ravage")
false
Object Augmentation in Prototypes
In the same way we used object augmentation to add new properties to an object, we can use the same concept to add new properties to a prototype and, hence, make those properties available to any object that has that prototype:
> function Barbarian(name){this.name = name;}
undefined
> var conan = new Barbarian("conan");
undefined
> var logenNinefingers = new Barbarian("The Bloody Nine")
undefined
> var shivers = new Barbarian("Caul Shivers");
undefined
> shivers.ravage
undefined
> Barbarian.prototype.ravage = function(){console.log(this.name + " attaaaaack!!");}
> conan.ravage()
"conan attaaaaack!!"
> logenNinefingers.ravage()
"The Bloody Nine aattaaaaack!!"
> shivers.ravage()
"Caul Shivers attack!!"
And so, we can see how after adding the ravage
method to the prototype, instances of Barbarian
that had been created previously, suddenly and auto-ma-gi-ca-lly get a new method. :O
Method Overriding
In order to override a method in JavaScript you will need to provide a new implementation of the method in your constructor
:
> function Barbarian(name){
this.name = name;
}
undefined
> var conanTheBarbarian = new Barbarian("Conan The Barbarian");
undefined
> conanTheBarbarian.toString()
"[object Object]"
> function Barbarian(name){
this.name = name;
this.toString = function(){
return "Barbarian: " + name;
};
}
undefined
> var conanTheDestroyer = new Barbarian("Conan The Destroyer!!!");
undefined
> conan.toString()
"Barbarian: Conan The Destroyer!!!"
Or in one of the prototypes in the prototype chain:
> function Barbarian(name){
this.name = name;
}
undefined
> var conan = new Barbarian("Conan The Barbarian");
undefined
> conan.toString()
"[object Object]"
> Barbarian.prototype.toString = function (){
return "Barbarian: " + name;
};
undefined
> conan.toString()
"Barbarian: Conan The Destroyer!!!"
This is called shadowing
just like in C#. Additionally, you can call your base prototype method by making use of JavaScript apply and call functions as illustrated in the example below:
// Create an inheritance hierarchy:
// BarbarianKing -> Barbarian -> Object
function Barbarian() {
this.title = 'the Scavenger from the Highlands'
}
Barbarian.prototype.warCry = function(message) {
console.log(message)
console.log('Waaaaaaaaaaahhhhh!')
}
function BarbarianKing() {
this.title = 'the King of Thieves'
}
BarbarianKing.prototype = Object.create(Barbarian.prototype)
BarbarianKing.prototype.constructor = BarbarianKing
// Override method warCry and call method from super prototype
BarbarianKing.prototype.warCry = function(message) {
Barbarian.prototype.warCry.call(this, message)
console.log('I am the ' + this.title + '!!!!')
}
// execute previous file by copy-pasting on chrome dev tools console
> var conan = new Barbarian()
undefined
> conan.warCry("Good morning, how are you doing good sir? Now Die!")
Good morning, how are you doing good sir? Now Die!
Waaaaaaaaaaaaaaaaah!
> var kingConan = new BarbarianKing()
undefined
> kingConan.warCry("!!!!hhhhhhaaaaaaW")
!!!!hhhhhhaaaaaaW
Waaaaaaaaaaaaaaaaah!
I am the King of the Thieves!
If you are not familiar with the apply
and call
methods, you just need to know that they let you call a function and explicitly specify the object that this
will refer to within the scope of the function:
> var conan = {
name: "conan",
sayHi: function(message){console.log(message + " " + this.name);}
}
undefined
> var logen = {
name: "logen"
}
undefined
> conan.sayHi("hello I am")
hello I am conan
> conan.sayHi.call(logen, /* message */ "hello I am")
hello I am logen
> conan.sayHi.apply(logen, /*arguments*/["hello I am"])
hello I am logen
> conan.sayHi("hello I am")
hello I am conan
In the previous example you can see how, even though we have defined the sayHi
method in the conan
object, by using apply
and call
we can borrow the method and use it on a different object logen
. For additional information, take a look at the awesome MDN docs on apply and call.
Emulating Classical Inheritance in JavaScript
Building on what we have learned so far, we can emulate classical inheritance as we known it in C# by:
- Making use of prototypical inheritance to ensure that any instance of an object inherits methods from its prototypes
- Making sure that each constructor function calls its base type constructor function using
call
orapply
so that any instance of an object contains all properties defined in each and every constructor.
I’ll illustrate this through an example:
// Inheritance Hierarchy:
// Barbarian -> DrawableGameObject -> MobileGameObject
function Position(x, y) {
this.x = x
this.y = y
}
Position.prototype.toString = function() {
return '[' + this.x + ',' + this.y + ']'
}
function MobileGameObject(position) {
this.position = position
}
MobileGameObject.prototype.move = function(newPosition) {
console.log('moving ' + this + ' to ' + newPosition)
this.position = newPosition
}
function DrawableGameObject(position, sprite) {
// call base type constructor function
MobileGameObject.apply(this, position)
this.sprite = sprite
}
// establish prototypical inheritance
// between DrawableGameObject and MobileGameObject
DrawableGameObject.prototype = Object.create(MobileGameObject.prototype)
DrawableGameObject.prototype.constructor = DrawableGameObject
DrawableGameObject.prototype.draw = function() {
console.log('drawing sprite: ' + this.sprite)
// draw sprite
}
function Barbarian(name, position, sprite) {
// call base type constructor function
DrawableGameObject.call(this, position, sprite)
this.name = name
}
// establish prototypical inheritance
// between Barbarian and DrawableGameObject
Barbarian.prototype = Object.create(DrawableGameObject.prototype)
Barbarian.prototype.constructor = Barbarian
Barbarian.prototype.toString = function() {
return this.name + '!!!'
}
// copy paste code from the example of the Chrome Dev Tools console
> var conan = new Barbarian("Conan", new Position(0,0), "conan.jpg");
undefined
> conan.move(new Position(5,5))
moving Conan!!! to [5,5]
> conan.draw()
drawing sprite: conan.jpg
Polymorphism
_Polymorphism_ allows a function to be written to take an object of a certain type T, but also work correctly if passed an object that belongs to a type S that is a subtype of T
Polymorphism in JavaScript will be the least of your problems. As a dynamically typed language, JavaScript exhibits what is known as duck typing, whereby an object’s semantics are based on the object’s own methods and properties and not on the inheritance chain or interface implementations (like in C#).
But this is probably best illustrated through an example. Imagine a roguelike RPG, and a game scene with our mighty hero bravely venturing herself inside an eery dungeon, risking her life for adventure and profit, turning a corner into a host of ravenous ghouls…
function Character(name){
this.name = "",
this.draw = function(){ // draw a character }
}
function Zombie(){
this.eatBrains = function(){ // mmmmm braaains }
this.draw = function() { // draw a zombie }
}
function Skeleton(){
this.creepyLaugh = function(){ // muhahahaha }
this.draw = function() { // draw a skeleton}
}
// etc
var redSonja = new Character("red sonja");
var zombie = new Zombie();
var skeleton = new Skeleton();
// etc
var scene = {
entities :[
redSonja, ghouls, zombie, skeleton, orc, dragon, priest, warlock, walls, pottery, tapestries
],
draw() : {
entities.forEach(function(entity){
entity.draw(); // duck typing style polymorphism right here
});
}
}
So, as long as an object has the draw
method, it will behave as something that can be drawn regardless of inheritance. And thus the popular saying that you may have heard in the past…
If it walks like a duck, swims like a duck and quacks like a duck, I call it a duck.
Appendix A. Classes in JavaScript, Welcome ECMAScript 6
Somewhere above in this article I said something like ”… there are not such thing as classes in JavaScript…” and I was telling the truth. You may be interesting in knowing that classes are a part of the specification of the next version of JavaScript - ECMAScript6 Harmony.
class MobileGameObject {
constructor(position) {
this.position = position
}
move(newPosition) {
// draw sprite
}
}
class DrawableGameObject extends MobileGameObject {
constructor(position, sprite) {
super(position)
this.sprite = sprite
}
draw() {
// draw sprite
}
}
class Barbarian extends DrawableGameObject {
constructor(name, sprite) {
super(new Position(0, 0), sprite)
this.name = name
}
toString(message) {
//...
}
}
It looks awesome, doesn’t it? (Even though it is just syntactic sugar over all the concepts you have seen in this article).
For more information regarding ECMAScript 6 Harmony take a look at @lukehoban great summary at GitHub
Appendix B. A Note About this
in JavaScript
To us C# developers used to the reliable value of this
, JavaScript can be a little bit crazy and confusing. The only thing you need to know to be able to use this
without fear in JavaScript is to forget how it works in C# and understand the following:
The
this
parameter refers to an object that’s implicitly associated with the function invocation as is termed the function context. (…)(…)as it turns out, what this parameter points to isn’t, as in Java, defined by how the function is declared, but by how it is invoked.
So:
- If a function is invoked as a method in the context of an object (e.g.
conan.sayHi()
)this
will point to the object itself. (Like in C#) - If a function is invoked as a function (e.g. helloWorld())
this
will be set towindow
. If you are using strict mode ("use strict";
),this
will beundefined
saving you from unexpected errors. - If a function is invoked as a constructor with the new keyword then
this
will be a new object. - If a function is invoked with
call
orapply
we can set thethis
to point at whatever our heart desires
> var conan = {whosThis : function(){console.log(this);}}
undefined
// 1) invoke as a method
> conan.whosThis()
Object {whosThis: function}
// 2) invoke as a function
> var whosThis = conan.whosThis
undefined
> whosThis()
Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
// 3) invoke as a constructor
> var o = new whosThis();
conan.whosThis {}
// 4.a) invoke with call
> whosThis.call({a: "1", b: "2"})
Object {a: "a", b: "b"}
// 4.b) invoke with apply
> whosThis.apply({a: "1", b: "2"})
Object {a: "a", b: "b"}
For more detailed information about the uses of this
in JavaScript visit the MDN documentation. In addition to the above, you can use the bind
method to create functions that are for ever bound to a specific object.
In Closing
So finally! Now that you are able to master the unwieldy JavaScript OOP arcane and take advantage of all the freedom and craziness this beautiful language has to offer, go off and build something awesome!
Fare thee well friend! ^ _ ^
Interested in Learning More JavaScript? Buy the Book!
Are you a C# Developer interested in learning JavaScript? Then take a look at the JavaScript-mancy book, a complete compendium of JavaScript for C# developers.
Have a great week ahead!! :)
More Articles In This Series
- Chapter 0: The Basic Ingredients of JavaScriptMancy
- Chapter 1: The Many a One JavaScript Quirks
- Functions
- Object Oriented Programming
- Basics
- ES6
- OOP
- Introduction to OOP in JavaScript for C# Developers
- Summoning Fundamentals: Introduction to OOP In JavaScript – Encapsulation
- Summoning Fundamentals: Introduction to OOP In JavaScript – Inheritance
- Summoning Fundamentals: Introduction to OOP In JavaScript – Polymorphism
- White Tower Summoning: Mimicking C# Classical Inheritance in Javascript
- White Tower Summoning Enhanced: The Marvels of ES6 Classes
- Black Tower Summoning: Object Composition with Mixins
- Safer JavaScript Composition With Traits and Traits.js
- JavaScript Ultra Flexible Object Oriented Programming with Stamps
- Object Oriented JavaScript for C# Programmers
- Tooling
- Data Structures
- Functional Programming
- And more stuff to be shaped out:
- Functional Programming with JavaScript
- Modules
- Asynchronous Programming
- The JavaScript Ecosystem
Other Awesome Resources
- JavaScript for C# Developers at Pluralsight
- JavaScript The Right Way
- Learning JavaScript Design Patterns by Addy Osmani
- JavaScript RoadTrip Part 3 at CodeSchool
P.S.1. I had envisioned writing something more about higher level constructs to organize your code, and common design patterns, drawing parallels to the .NET world but I fear this article would have become undesirably long. I hope you will share my opinion and won’t be to hard on me if I leave it for a future article.
P.S.2. Still Not Liking JavaScript? Take a look at TypeScript then! :)
Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.