Overheard at work today:
“…this is why I hate JavaScript so much.”
Sound like something you’d say? Instead of letting the hate flow through you, know that it doesn’t have to be like that. JavaScript is evolving quickly and picking up luxuries that C# has had for years.
Subtle Differences
Before I get into the cooler, newer parts of JavaScript, a few key differences from C# that you should really know about:
- Equality checking. Use triple equals (===) for common, everyday equality checking (or !== for inequality). Avoid double equals (==) due to some hidden gotchas.
- Variable declarations. Variables instantiated with var do not behave how you expect. They’re lexically scoped as opposed to the block scoping of C# and most other languages. e.g. vars created inside of for loops and if blocks are visible beyond the curly braces. The 2015 edition introduces let, which works like C#’s var.
Language Features
JavaScript went several years between editions: the third edition was released in 1999, the fifth edition in 2009. Not anymore – the sixth edition was published June 2015 and included a proposal for two-year release cycles. Some of the new features include:
-
- LINQ. Code written with LINQ is generally more declarative and expressive than code that isn’t, and it’s easily within reach when writing JS. Similar functions for arrays exist in JS, they’re just named differently:
- map instead of Select
- filter instead of Where
- sort instead of OrderBy
- LINQ. Code written with LINQ is generally more declarative and expressive than code that isn’t, and it’s easily within reach when writing JS. Similar functions for arrays exist in JS, they’re just named differently:
// C# var philly = new MenuItem("philly", "fries", 10.99m); var reuben = new MenuItem("reuben", "fries", 9.99m); var pizza = new MenuItem("pizza", "salad", 16.99m); var menu = new [] { philly, reuben, pizza }; var choices = menu .Where(x => x.Side == "fries") .OrderBy(x => x.Price) .Select(x => x.Name); // choices => ["reuben", "philly"]
// JS var philly = { name: "philly", side: "fries", price: 10.99 } var reuben = { name: "reuben", side: "fries", price: 9.99 } var pizza = { name: "pizza", side: "salad", price: 16.99 } var menu = [philly, reuben, pizza]; var choices = menu .filter(x => x.side === "fries") .sort((x, y) => x.price > y.price) .map(x => x.name); // choices => ["reuben", "philly"]
-
- Class syntax. Introduced in ES6, the class syntax makes creating classes look much more familiar to the usual C# style. There are still fundamental differences in how inheritance works in JS vs. C#, but a similar syntax will help smooth some of that over.
// C# class Address { private readonly string _city; private readonly string _state; private readonly string _zip; public Address(string city, string state, string zip) { _city = city; _state = state; _zip = zip; } public string ToFormattedString() { return _city + ", " + _state + " " + _zip; } }
// JS class Address { constructor(city, state, zip) { this.city = city; this.state = state; this.zip = zip; } toFormattedString() { return this.city + ", " + this.state + " " + this.zip; } }
-
- String interpolation. JavaScript’s version of string interpolation uses backtick (`) characters. Must be using ES6 or later. Use it like so:
// C# var number = 3; var size = "large"; return $"I'll take {number} {size} pizzas, please";
// JS var number = 3; var size = "large"; return `I'll take ${number} ${size} pizzas, please`;
Development Environment
Both the development environment and tools that are available to you for a given language greatly affect your productivity and experience for that language, irrespective of the language itself. Visual Studio, despite being a bit sluggish at times, is a great development environment to work in. Popular JavaScript IDEs tend to be less IDE and more text editor, which makes them feel quicker and more responsive.
- Powerful IDE with community plugins. What makes VS even better is the plugin ecosystem, ranging from the essential ReSharper to the tiny Hide Main Menu (personal favorite). For JavaScript, Sublime is hugely popular, and more recently Atom by GitHub, which both offer a fantastic set of user-created packages and themes. There’s also the lightweight Visual Studio Code, which supports both C# and JS!
- ReSharper-style suggestions. Even though JavaScript is an interpreted language, front end developers have recognized the value in catching potential errors before execution. In Sublime, adding the SublimeLinter package (plus a little bit of configuration) gives you static code analysis à la ReSharper. Examples include removing unused variables, removing unreachable code, and requiring a default case in switch statements.
- Importing. Gone are the days where you have to include a multitude of scripts on the page in a particular order. Just like in statically typed languages like C#, you can use import statements in your JS files to reference other files, which are then built with a tool like webpack or Browserify. Throw NodeRequirer into the mix, an Intellisense-like plugin for Sublime for finding files, and you’ll feel right at home.
- Package manager. NuGet is handy, but npm is handier.
Testing
JavaScript development is a wild west of roughly thrown together code, with undefined is not a function hiding under every rock, right? Wrong!
-
- Unit testing. Popular testing frameworks include Jest and Mocha, with Karma as a kickass test runner – it even has the ability to rerun the test suite when a .js file changes! Test-driven development is popular in .NET communities, and JS developers are starting to embrace it – for example, this Redux tutorial is written in TDD style.
// C# [Test] public void Should_return_true_for_valid_prime_number() { var isPrime = _classUnderTest.IsPrimeNumber(37); isPrime.Should().Be(true); }
// JS describe("isPrimeNumber", function () { it("should return true for valid prime number", function () { var isPrime = isPrimeNumber(37); expect(isPrime).to.be(true); }); });
Server-side
Historically, JavaScript has always been known as a client-side language, but node.js has completely changed that notion.
// C# public class SandwichesController : ApiController { public ActionResult Index(int id) { // do stuff with the request and response } }
// JS var express = require("express"); var app = express(); app.get("/v2/sandwiches/:id", function (request, response) { var sandwichId = request.params.id; // do stuff with the request and response }
Conclusion
JavaScript isn’t so bad, right?