JavaScript for Data Analysts
Me
- Software Engineer at Urban Center for Computation and Data
- willengler@uchicago.edu
- Lincoln in the Bardo by George Saunders lives up to the hype
Goals
- Know the basics of JavaScript, and how it's used
- Give you enough context such that if you ever need to write JS, you can dive in effectively.
Outline
- History
- Language tour
- Effective asynchronous JS
- Data visualization
JavaScript's Torrid History
1995: A War for the Browser
- Sun was pushing Java applets for rich applications over the internet
- Netscape wanted to support a Hypercard-like model where a scripting language could be used within web pages
And on the 10th Day...
- Netscape hired Brendan Eich to write a Scheme interpreter (or so he thought)
- The new language needed to ride the Java and object-oriented hype train
- After 10 DAYS of development, JavaScript was born.
"A LISP in C's Clothing"
- Java: Curly brace syntax (C/ALGOL style)
- Scheme: Functions
- Self: Prototypal inheritance
2005: The Invention of AJAX
- Google's Gmail and Maps start blurring the boundaries between web pages and web applications
- A seminal blog post coins the term AJAX: asynchronous JavaScript and XML
- AJAX wasn't new tech - just a design pattern
2008: The V8 Engine Debuts
- V8 engine debuts with Google Chrome
- Previous JS engines were interpreted
- V8 is JIT compiled and contains many other clever optimizations
V8 Spreads
-
2009: Node.js
- Single-threaded runtime targeted to network bound server applications
- 2010: Node Package Manager (NPM)
- 2013: Electron
- Framework for desktop applications - used by Atom, Slack, Visual Studio Code
A Language Tour
How to Start Playing with JS
- Easiest: Open your browser's dev console
- A little effort: Write a .html file, embed some JS in a <script> tag, and open the file in a browser
- Getting serious: Install Node on your system
Objects
// Objects are collections that map strings
// to values of any type
var myObject = {
foo: 1
bar: 'fizz'
}
// String dereference
myObject.foo // 1
// Expression dereference
myObject['b' + 'ar'] // fizz
// Attribute assignment
myObject.bar = 'gorp'
Functions
// Function statement
function add(a, b) {
return a + b;
}
// Function expression (anonymous function AKA lambda)
function(a, b) {
return a + b;
}
// Functions are "first class"
// (you can create them and pass them around dynamically)
// and close over their parent function's scope
function makePrinter(message) {
return function() {
console.log(message)
}
}
var printUpbeatMessage = makePrinter("Isn't JS dandy?")
printUpbeatMessage() // "Isn't JS dandy?"
Bear in mind that it was made in 10 days
- Start this video at 1:20
Unfortunate features
Over-eager type coercion
2 == '2' // true!?!?
2 === '2' // false
// Lesson: you almost always want to use the === operator for equality checks
// == coerces, === does not
undefined and null
var myObject = {
foo: null
}
var a = myObject.foo // null
var b = myObject.bar // undefined
Boolean(a) // false
Boolean(b) // false
Standards Improvements
- Conflict between browser vendors long stood in the way of improving JavaScript standards (ECMAScript or "ES")
- 2009: ES5
- 2015: ES6
- The latest standards help you avoid some of the weirder parts of the language
"Don't Break the Web"
- New syntax added while preserving old syntax
- Developers transpile to older standards while browsers adopt new standards
Asynchronous JS
staying out of callback hell
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})
Taken from callbackhell.com
Why is this a thing?
- It's not as if JS is particularly well-suited to asynchronous programming
- It's history in the browser meant that blocking on IO was a nonstarter
- This philosophy is central to Node.js
Rightward Drift
// Getting into callback hell
$.ajax('https://my.api.com/will').done(function(userResponse) {
let link = response.body.friends;
$.ajax(link).done(function(friendsResponse) {
for (let friend of friendsResponse) {
let imgLink = friend.profilePicture;
$.ajax(imglink).done(function(imageBlob) {
imageBoard.push(imageBlob);
})
}
})
});
Naming Functions
// Breaking out into functions
let addImageToBoard = (imageBlob) => imageBoard.push(imageBlob);
function fetchFriendImages(userResponse) {
for (let friend of friendsResponse) {
let imgLink = friend.profilePicture;
$.ajax(imglink).done(addImageToBoard);
}
}
$.ajax('https://my.api.com/will').done(function(userResponse) {
let link = userResponse.friends;
$.ajax(link).done(fetchFriendImages);
});
Using Promises
// Writing sequential-looking code with promises
fetch('https://my.api.com/will')
.then(userResponse => fetch(userResponse.friends))
.then(friendResponse => {
let imgPromises = friendResponses.map(f => fetch(f.profilePicture));
return Promise.all(imgPromises);
})
.then(images => {
for (let img of images) {
imageBoard.push(img);
}
});
Data Visualization
A Library Tour
D3 is Cool, Right?
- Yes! But not great for beginners.
- D3 is intended to provide low-level graphing primitives - an API to create SVGs that react to your data
- Unless you're creating a special snowflake, you probably should start by taking a look at libraries like c3, Rickshaw, Highcharts, and nvd3
Mapping
- Leaflet is worth learning in depth
- Blog post walking through a Chicago visualization
Learn More
Title Text
- Crockford lectures
- Mozilla JS docs
- Exploring ES6 by Axel Rauschmayer
JavaScript for Data Analysts
By Will Engler
JavaScript for Data Analysts
Chapin Hall 3/29/17
- 767