On Github treyhunner / js-like-python
My name is Trey. I'm going to show you how JavaScript is becoming more like Python.
A word of warning: I will be going very quickly and there are code examples on almost every slide.
ECMAScript is the language specification that JavaScript is based on.
In this presentation I'm going to show off features that were added in ECMAScript 6, also known as ECMAScript 2015.
ECMAScript 6 isn't yet supported by browsers, but you can start using it today...
You just need to use Babel.
Babel allows you to compile your ES6 code down to ES5 code, which is understood by all modern web browsers.
This is a pre-compilation process, which is kind of like the pre-compilation step necessary for using something like CoffeeScript.
from functools import reduce numbers = [1, 2, 3, 4] reduce(lambda x, y: x * y, numbers)
let numbers = [1, 2, 3, 4]; numbers.reduce((x, y) => x * y);
Our first new feature is fat arrows.
Fat arrows are a new shortened function syntax.
So fat arrows can be used kind of like lambda functions.
Fat arrows also have a longer syntax, but I'm only showing off the short one in my slides.
We don't use lambdas very often in Python partially because we don't use callbacks often. In JavaScript we use callbacks all the time, so fat arrows are really useful.
sorted(u.name for u in users if u.is_active)
users.filter(u => u.isActive).map(u => u.name).sort();
When you combine fat arrow functions with JavaScript's array methods, they can serve the same purpose as list comprehensions.
In addition to being easier on the eyes, fat arrow functions inherit the "this" binding of their outer scope.
For anyone who has wrestled with JavaScript function binding, that's a really big deal.
from datetime import datetime date = datetime.now() print("The year is {date.year}".format(date=date))
let date = new Date(); console.log(`The year is ${date.getFullYear()}`);
With Template strings you can now do string interpolation in JavaScript.
You create template strings using backticks. Unlike Python's format method, template strings interpolate using the current scope automatically.
poem = """Programming is fun Except for syntax errors Missing curly brace"""
let poem = `Programming is fun Except for syntax errors Missing curly brace`;
Template strings also allow you to make multi-line strings. So you can use template strings like triple-quoted strings in Python.
class Point: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "({x}, {y})".format(x=self.x, y=self.y)
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${this.y})`; } }
JavaScript did not used to have a class syntax. It does now.
This is what it looks like.
Of course no class implementation is complete without a properly-loaded foot gun. So JavaScript also supports...
class ColorPoint(Point): def __init__(self, x, y, color): super().__init__(x, y) self.color = color def __str__(self): return "{super} in color {color}".format( super=super().__str__(), color=self.color )
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return `${super.toString()} in ${this.color}`; } }
Inheritance.
I actually think the "super" syntax is a little more elegant in JavaScript than it is in Python.
import datetime date_fields = (2015, 6, 12); date = datetime.date(*date_fields)
let dateFields = [2015, 5, 12]; let date = new Date(...dateFields);
JavaScript now has a spread operator. This is similar to Python's argument unpacking operator. In Python this is an asterisk, in JavaScript this operator is three dots.
You can use it to unpack an array into the arguments of a function call.
first = [1, 2] second = [3, 4] combined = first + second
let first = [1, 2]; let second = [3, 4]; let combined = [...first, ...second];
You can also use the spread operator to unpack one array inside of another array.
In this example combined would be the array [1, 2, 3, 4].
def most_difference(*numbers): return max(numbers) - min(numbers)
function mostDifference(...numbers) { return Math.max(...numbers) - Math.min(...numbers); }
The rest operator is basically the opposite of the spread operator. Again instead of an asterisk, this operator is three dots.
This allows us to make functions that take a variable number of arguments. For example our mostDifference function here takes any number of arguments.
This code example shows both the "rest" operator used once and "spread" operator used twice.
def greet(name="world"): return "Hello {name}!".format(name=name)
function greet(name='world') { return `Hello ${name}!`; }
JavaScript now allows you to specify default parameter values.
This does not mean JavaScript has keyword arguments. It doesn't. These are just default values for positional arguments.
coordinate = (1, 4, 2) x, y, z = coordinate
let coordinate = [1, 4, 2]; let [x, y, z] = coordinate;
Just like Python, JavaScript now has iterable unpacking. You can unpack arrays into multiple variables and you can also use this for multiple assignment and variable swapping.
Here, x, y, and z would be 1, 4, and 2.
@memoize def get_divisors(number): return big_computation(number)
@memoize function getDivisors(number) { return bigComputation(number); }
This one is actually wishful thinking because this is only a proposed feature.
The currently proposed syntax for JavaScript decorators looks just like Python's decorator syntax.
So hopefully JavaScript will have decorators soon.
import urls from utils import jsonify, memoize
import urls from 'urls.js'; import {jsonify, memoize} from 'utils.js';
JavaScript actually has modules now. They're properly namespaced and they work pretty similarly to the way modules work in Python.
Learn ES2015: https://babeljs.io/docs/learn-es2015/
Try it out: http://babeljs.io/repl
So I just showed you a small handful of new features supported by JavaScript.
You can learn more about Babel and try it out right from your web browser by going to the Babel website.
Feel free to reach out to me on Twitter if you have any questions.