JavaScript Writ Large Douglas Crockford Yahoo! Inc. The World's - - PowerPoint PPT Presentation

javascript writ large
SMART_READER_LITE
LIVE PREVIEW

JavaScript Writ Large Douglas Crockford Yahoo! Inc. The World's - - PowerPoint PPT Presentation

JavaScript Writ Large Douglas Crockford Yahoo! Inc. The World's Most Popular Programming Language The World's Most Unpopular Programming Language JavaScript was supposed to be a HyperTalk-like language. The goal for Netscape Navigator 2


slide-1
SLIDE 1

JavaScript Writ Large

Douglas Crockford Yahoo! Inc.

slide-2
SLIDE 2

The World's Most Popular Programming Language The World's Most Unpopular Programming Language

slide-3
SLIDE 3

JavaScript was supposed to be a HyperTalk-like language.

The goal for Netscape Navigator 2 was to provide HyperCard-like functionality in a web browser.

slide-4
SLIDE 4

When Ajax gave JavaScript second chance, it succeeded because the language works.

slide-5
SLIDE 5

The language has very good parts, and very bad parts.

By subsetting the language, you get a much better language.

slide-6
SLIDE 6

JavaScript is not like any other language you have ever used.

Probably. So you need to adapt.

slide-7
SLIDE 7

The language can handle projects of significant size and complexity.

How much pain you will have to endure will depend on your technique.

slide-8
SLIDE 8

The unit of pain is the agon.

slide-9
SLIDE 9

JavaScript Agon Reduction

  • 1. Adopt a rigorous style
  • 2. Avoid classical patterns
  • 3. Think functionally
  • 4. Think prototypally
  • 5. Beware the DOM
  • 6. Manage the divide
slide-10
SLIDE 10
  • 1. Adopt a rigorous style
  • Bother to learn the language first.
  • Use JSLint to constrain yourself to the

Good Parts.

  • Avoid global variables.
slide-11
SLIDE 11
slide-12
SLIDE 12

JSLint

  • JSLint defines a professional subset of

JavaScript.

  • It imposes a programming discipline that

makes me much more confident in a dynamic, loosely-typed environment.

  • http://www.JSLint.com/
slide-13
SLIDE 13

WARNING!

JSLint will hurt your feelings.

slide-14
SLIDE 14

Avoid global variables

  • Global variables are evil.
  • Lacking any form of linker, JavaScript

uses global variables to bind separate compilation units together.

  • Variables are a global by default!
slide-15
SLIDE 15

Define at most one global variable per compilation unit

  • Use the global space as though it is

package space.

  • Do not put any ordinary variables in global

space.

  • Instead put whole objects in global space.
  • Write global variables all in UPPERCASE!
slide-16
SLIDE 16

A single container in global space

var MYAPP = { important_variable: true, key_method: function (...) { ... } };

slide-17
SLIDE 17
  • 2. Avoid classical patterns
  • JavaScript is not Java.
  • It is class-free.
  • It is powerful enough to simulate a

classical style.

  • It likes very shallow hierarchies.
  • It is dynamic.
  • It is loosely typed.
slide-18
SLIDE 18

If you find yourself needing super methods, then you aren't ready yet.

slide-19
SLIDE 19
  • 3. Think functionally

Functions are used as

  • Functions
  • Methods
  • Constructors
  • Classes
  • Modules
slide-20
SLIDE 20

Functions are first-class values

  • Functions can be stored in variables, in
  • bjects (methods), passed as arguments,

and returned.

  • Functions can be defined inside of other

functions with lexical (or static) scoping.

  • A function has access to the variables and

parameters of the functions it is contained within.

slide-21
SLIDE 21

Global

var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; var digit_name = function (n) { return names[n]; }; alert(digit_name(3)); // 'three'

slide-22
SLIDE 22

Slow

var digit_name = function (n) { var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; return names[n]; }; alert(digit_name(3)); // 'three'

slide-23
SLIDE 23

Closure

var digit_name = (function () { var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; return function (n) { return names[n]; }; }()); alert(digit_name(3)); // 'three'

slide-24
SLIDE 24

Use functions to make functions

var make_add_x = function (x) { return function (y) { return x + y; }; }; var add_2 = make_add_x(2); alert(add_2(7)); // 9

slide-25
SLIDE 25

Use functions to make functions

var make_f_x = function (f, x) { return function (y) { return f(x, y); }; }; var add_2 = make_f_x(add, 2); alert(add_2(7)); // 9

slide-26
SLIDE 26

Fibonacci

var fibonacci = function (n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); };

  • fibonacci(40)
  • Calls itself 331,160,280 times.
slide-27
SLIDE 27

Memoizer

var memoizer = function (memo, fundamental) { return function recur(n) { var result = memo[n]; if (typeof result !== 'number') { result = fundamental(recur, n); memo[n] = result; } return result; }; };

slide-28
SLIDE 28

Memoizer

var fibonacci = memoizer([0, 1], function (recur, n) { return recur(n - 1) + recur(n - 2); });

  • fibonacci(40)
  • Calls itself 38 times.
slide-29
SLIDE 29

Memoizer

var fibonacci = memoizer([0, 1], function (recur, n) { return recur(n - 1) + recur(n - 2); }); var factorial = memoizer([1, 1], function (recur, n) { return recur(n - 1) * n; });

slide-30
SLIDE 30

Use functions to make objects

1. Make an object.

  • Object literal
  • new
  • Object.create
  • call another constructor

(Functional Inheritance)

slide-31
SLIDE 31

Use functions to make objects

1. Make an object.

  • Object literal, new, Object.create, call

another constructor 2. Define some variables and functions.

  • These become private members.
slide-32
SLIDE 32

Use functions to make objects

1. Make an object.

  • Object literal, new, Object.create, call

another constructor 2. Define some variables and functions.

  • These become private members.

3. Augment the object with privileged methods.

slide-33
SLIDE 33

Use functions to make objects

1. Make an object.

  • Object literal, new, Object.create, call

another constructor 2. Define some variables and functions.

  • These become private members.

3. Augment the object with privileged methods. 4. Return the object.

slide-34
SLIDE 34

Step One

function myPowerConstructor(x) { var that = otherMaker(x); }

slide-35
SLIDE 35

Step Two

function myPowerConstructor(x) { var that = otherMaker(x); var secret = f(x); }

slide-36
SLIDE 36

Step Three

function myPowerConstructor(x) { var that = otherMaker(x); var secret = f(x); that.priv = function () { ... secret x ... }; }

slide-37
SLIDE 37

Step Four

function myPowerConstructor(x) { var that = otherMaker(x); var secret = f(x); that.priv = function () { ... secret x ... }; return that; }

slide-38
SLIDE 38

Use functions to make objects

  • Objects made with this pattern are robust

and tamper-proof.

  • We make objects with private state.
  • There is a cost of one function object per

method per instance.

  • Ideal if the number of instances is fewer

than hundreds.

slide-39
SLIDE 39
  • 4. Think prototypally
  • Objects can inherit directly from other
  • bjects.
  • Delegation, or differential inheritance.
  • In creating an object, you only need to

specify the properties that differ from its prototype.

  • Objects can be customized with simple

assignment.

  • No classes!
slide-40
SLIDE 40

Delegation

  • Every object contains a hidden property

that contains a reference to the object's prototype.

  • The chain always ends with

Object.prototype.

  • When fetching a property from an object, if

the object lacks a property with that name, then its prototype is searched and then its prototype is searched...

slide-41
SLIDE 41

Prototype

  • A popular pattern is to put common

methods into a prototype object.

  • There is then no memory or construction

cost for providing methods to instances through the prototype.

  • This is ideal when the number of instances

is thousands or more.

  • There is no privacy. All members are

public.

slide-42
SLIDE 42
  • 5. Beware of the DOM
  • If JavaScript were sped up to be infinitely

fast, most applications would run at about the same speed.

  • The DOM is a terrible bottleneck. HTML is

an inefficient display list.

  • When making large changes to the

display, innerHTML is significantly faster than the DOM API.

slide-43
SLIDE 43
  • 6. Manage the divide
  • The client and server are in a dialog.
  • Make the messages between them as

small as possible.

  • The client does not need a copy of the
  • database. It just needs, at any moment,

just enough information to serve the user.

  • Don't rewrite the server application in

JavaScript!

slide-44
SLIDE 44

Division of Labor

How is the application divided between the browser and the server?

slide-45
SLIDE 45

Pendulum of Despair

Server The browser is a terminal.

slide-46
SLIDE 46

Pendulum of Despair

Server Browser The browser is a terminal The server is a file system.

slide-47
SLIDE 47

Seek the Middle Way.

A pleasant dialogue between specialized peers.

slide-48
SLIDE 48

JavaScript Agon Reduction

  • 1. Adopt a rigorous style
  • 2. Avoid classical patterns
  • 3. Think functionally
  • 4. Think prototypally
  • 5. Beware the DOM
  • 6. Manage the divide
slide-49
SLIDE 49

The World's Most Misunderstood Programming Language