0% found this document useful (0 votes)
19 views70 pages

Ajax World

Uploaded by

Uvaldo pq
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views70 pages

Ajax World

Uploaded by

Uvaldo pq
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 70

JavaScript:

A Language of Many Contrasts




Douglas Crockford
Yahoo!
http://javascript.crockford.com/ajaxworld.ppt
The World's Most
Misunderstood
Programming Language
Sources of
Misunderstanding
The Name
Mispositioning
Design Errors
Bad Implementations
The Browser
Bad Books
Substandard Standard
JavaScript is a Functional
Language
Key Ideas
Load and go delivery
Loose typing
Objects as general containers
Prototypal inheritance
Lambda
Linkage through global variables
Key Ideas
Load and go delivery
Loose typing
Objects as general containers
Prototypal inheritance
Lambda
Linkage though global variables
It is full of warts.
For statement
Iterate through all of the members of
an object:

for (var name in object) {
if (object.hasOwnProperty(name)) {

// within the loop,
// name is the key of current member
// object[name] is the current value

}
}
typeof
The typeof prefix operator returns
a string identifying the type of a
value.
type typeof
object 'object'
function 'function'
array 'object'
number 'number'
string 'string'
boolean 'boolean'
null 'object'
undefined 'undefined'
with statement
Intended as a
short-hand

Ambiguous

Error-prone

Don't use it

with (o) {
foo = null;
}

o.foo = null;

foo = null;
It is mostly good
stuff.
Inner functions
Functions do not all have to be
defined at the top level (or left
edge).

Functions can be defined inside of
other functions.
Scope
An inner function has access to
the variables and parameters of
functions that it is contained
within.

This is known as Static Scoping or
Lexical Scoping.
Closure
The scope that an inner function
enjoys continues even after the
parent functions have returned.

This is called closure.
Example
function fade(id) {
var dom = document.getElementById(id),
level = 1;
function step () {
var h = level.toString(16);
dom.style.backgroundColor =
'#FFFF' + h + h;
if (level < 15) {
level += 1;
setTimeout(step, 100);
}
}
setTimeout(step, 100);
}
Inheritance
Inheritance is object-oriented
code reuse.

Two Schools:

Classical

Prototypal
Classical Inheritance
Objects are instances of Classes.

A Class inherits from another
Class.
Pseudoclassical
Pseudoclassical looks sort of classical,
but is really prototypal.

Three mechanisms:

Constructor functions.

The prototype member of functions.

The new operator.
Psuedoclassical
function Constructor() {
this.member = initializer;
return this; // optional
}

Constructor.prototype.firstMethod =
function (a, b) {...};
Constructor.prototype.secondMethod =
function (c) {...};

var newObject = new Constructor();
new operator
var newObject = new Constructor();

new Constructor() returns a new
object with a link to
Constructor.prototype.
Constructor.prototype newObject
Warning
The new operator is required when
calling a Constructor.

If new is omitted, the global object
is clobbered by the constructor,
and then the global object is
returned instead of a new
instance.
Syntactic Rat Poison
Constructor.
method('first_method',
function (a, b) {...}).
method('second_method',
function (c) {...});
-----------------------------------
Function.prototype.method =
function (name, func) {
this.prototype[name] = func;
return this;
};

Pseudoclassical Inheritance
Classical inheritance can be simulated
by assigning an object created by one
constructor to the prototype member
of another.

function BiggerConstructor() {...};
BiggerConstructor.prototype =
new Constructor();

This does not work exactly like the
classical model.
Example
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
Example
prototype
id string
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
constructor
toString function
prototype
constructor
toString function
new Gizmo(string)
Gizmo
Object
Example
prototype
id string
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
constructor
toString function
prototype
constructor
toString function
new Gizmo(string)
Gizmo
Object
Example
prototype
id string
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
constructor
toString function
prototype
constructor
toString function
new Gizmo(string)
Gizmo
Object
Inheritance
If we replace the original
prototype object with an instance
of an object of another class, then
we can inherit another class's
stuff.
Example
function Hoozit(id) {
this.id = id;
}
Hoozit.prototype = new Gizmo();
Hoozit.prototype.test = function (id) {
return this.id === id;
};
Example
prototype
prototype
function Hoozit(id) {
this.id = id;
}
Hoozit.prototype = new Gizmo();
Hoozit.prototype.test = function (id) {
return this.id === id;
};
test function
constructor
constructor
toString function
Gizmo
Hoozit
id string
new Hoozit(string)
Example
prototype
prototype
function Hoozit(id) {
this.id = id;
}
Hoozit.prototype = new Gizmo();
Hoozit.prototype.test = function (id) {
return this.id === id;
};
test function
constructor
constructor
toString function
Gizmo
Hoozit
id string
new Hoozit(string)
Prototypal Inheritance
Class-free.
Objects inherit from objects.
An object contains a secret link to
the object it inherits from.

var newObject = object(oldObject);
newObject
__proto__
oldObject
object function
A prototypal inheritance language
should have an operator like the
object function, which makes a
new object using an existing
object as its prototype.

object function
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
object function
prototype
F
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
newObject = object(oldObject)

constructor
object function
prototype
F
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
newObject = object(oldObject)

oldObject
constructor
object function
prototype
F
newObject
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
newObject = object(oldObject)

oldObject
object function
newObject
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
newObject = object(oldObject)

oldObject
Prototypal Inheritance
var oldObject = {
firstMethod: function () {...},
secondMethod: function () {...}
};

var newObject = object(oldObject);

newObject.thirdMethod = function () {...};

var myDoppelganger = object(newObject);

myDoppelganger.firstMethod();
Prototypal Inheritance
There is no limit to the length of
the chain (except common sense).
oldObject
myDoppelganger = object(newObject);
newObject
Augmentation
Using the object function, we can
quickly produce new objects that
have the same state and behavior
as existing objects.

We can then augment each of the
instances by assigning new
methods and members.
Public Method
A Public Method is a function that
uses this to access its object.
This binding of this to an object
happens at invocation time.
A Public Method can be reused
with many "classes".
Public Methods
myObject.method = function (string) {
return this.member + string;
};

We can put this function in any object
at it works.

Public methods work extremely well
with prototypal inheritance and with
pseudoclassical inheritance.
Singletons
There is no need to produce a
class-like constructor for an
object that will have exactly one
instance.

Instead, simply use an object
literal.
Singletons
var singleton = {
firstMethod: function (a, b) {
...
},
secondMethod: function (c) {
...
}
};
Functions are used as
Functions
Methods
Constructors
Classes
Modules
Module
Variables defined in a module are
only visible in the module.

Functions have scope.

Variables defined in a function
only visible in the function.

Functions can be used a module
containers.
Global variables are evil
Functions within an application
can clobber each other.

Cooperating applications can
clobber each other.

Use of the global namespace must
be minimized.
Singletons
The methods of a singleton can
enjoy access to shared private
data and private methods.
Singletons
var singleton = function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}

return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
}();
Applications are Singletons
var AJAX = function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}

return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
}();

Privacy
All members of an object are
public.

We want private variables and
private methods.

Really.
Privileged Method
A Privileged Method is a function that
has access to secret information.

A Privileged Method has access to
private variables and private methods.

A Privileged Method obtains its secret
information through closure.
Power Constructor
Put the singleton module pattern
in constructor function, and we
have a power constructor
pattern.

1. Make a new object somehow.

2. Augment it.

3. Return it.
Power Constructor
function powerConstructor() {
var that = object(oldObject),
privateVariable;
function privateFunction(x) { ... }

that.firstMethod = function (a, b) {
...privateVariable...
};
that.secondMethod = function (c) {
...privateFunction()...
};
return that;
}
Power Constructor
Public methods (from the
prototype)
var that = object(oldObject);
Private variables (var)
Private methods (inner functions)
Privileged methods
No need to use new
myObject = power_constructor();
Parasitic Inheritance
A power constructor calls another
constructor, takes the result,
augments it, and returns it as
though it did all the work.
Psudeoclassical Inheritance
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};

function Hoozit(id) {
this.id = id;
}
Hoozit.prototype = new Gizmo();
Hoozit.prototype.test = function (id) {
return this.id === id;
}
Parasitic Inheritance
function gizmo(id) {
return {
id: id,
toString: function () {
return "gizmo " + this.id;
}
};
}

function hoozit(id) {
var that = gizmo(id);
that.test = function (testid) {
return testid === this.id;
};
return that;
}
Secrets
function gizmo(id) {
return {
toString: function () {
return "gizmo " + id;
}
};
}

function hoozit(id) {
var that = gizmo(id);
that.test = function (testid) {
return testid === id;
};
return that;
}
Shared Secrets
function gizmo(id, secret) {
secret = secret || {};
secret.id = id;
return {
toString: function () {
return "gizmo " + secret.id;
};
};
}

function hoozit(id) {
var secret = {},
that = gizmo(id, secret);
that.test = function (testid) {
return testid === secret.id;
};
return that;
}
Super Methods

function hoozit(id) {
var secret = {},
that = gizmo(id, secret),
super_toString = that.toString;
that.test = function (testid) {
return testid === secret.id;
};
that.toString = function () {
return super_toString.apply(that, []);
};
return that;
}
Inheritance Patterns
Prototypal Inheritance works
really well with public methods.

Parasitic Inheritance works really
well with privileged and private
and public methods.

Pseudoclassical Inheritance for
elderly programmers who are old
and set in their ways.
Working with the Grain
Pseudoclassical patterns are less
effective than prototypal patterns
or parasitic patterns.

Formal classes are not needed for
reuse or extension.

Be shallow. Deep hierarchies are
not effective.
Performance
Provide a good experience.

Be respectful of our customer's
time.

Hoare's Dictum: Premature
optimization is the root of all evil.
Efficiency
The first priority must always be
correctness.

Optimize when necessary.

Consider algorithmic improvements

O (n) v O (n log n) v O (n
2
)

Watch for limits.
Minification vs
Obfuscation
Reduce the amount of source
code to reduce download time.
Minification deletes whitespace
and comments.
Obfuscation also changes the
names of things.
Obfuscation can introduce bugs.
Never use tools that cause bugs if
you can avoid it.
http://www.crockford.com/javascript/jsmin.html
Code Conventions for the
JavaScript Programming
Language

http://javascript.crockford.com/code.html
JSLint
JSLint can help improve the
robustness and portability of your
programs.
It enforces style rules.
It can spot some errors that are very
difficult to find in debugging.
It can help eliminate implied
globals.
Commandline versions.
In text editors and Eclipse.
JSLint
Warning: JSLint will hurt your
feelings.

If you follow its advice, JSLint will
make your programs better.

http://www.JSLint.com/
JavaScript:
A Language of Many Contrasts


Douglas Crockford
Yahoo!
http://javascript.crockford.com/ajaxworld.ppt

You might also like