Ajax World
Transcript of Ajax World
![Page 1: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/1.jpg)
JavaScript:A Language of Many Contrasts
Douglas CrockfordYahoo!
http://javascript.crockford.com/ajaxworld.ppt
![Page 2: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/2.jpg)
The World's Most Misunderstood Programming
Language
![Page 3: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/3.jpg)
Sources of Misunderstanding• The Name• Mispositioning• Design Errors• Bad Implementations• The Browser• Bad Books• Substandard Standard• JavaScript is a Functional Language
![Page 4: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/4.jpg)
Key Ideas• Load and go delivery• Loose typing• Objects as general containers• Prototypal inheritance• Lambda• Linkage through global variables
![Page 5: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/5.jpg)
Key Ideas• Load and go delivery• Loose typing• Objects as general containers• Prototypal inheritance• Lambda• Linkage though global variables
![Page 6: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/6.jpg)
It is full of warts.
![Page 7: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/7.jpg)
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
}}
![Page 8: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/8.jpg)
typeof
• The typeof prefix operator returns a string identifying the type of a value.
type typeofobject 'object'function 'function'array 'object'number 'number'string 'string'boolean 'boolean'null 'object'undefined 'undefined'
![Page 9: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/9.jpg)
with statement• Intended as a
short-hand
• Ambiguous
• Error-prone
• Don't use it
with (o) { foo = null;}
o.foo = null;
foo = null;
![Page 10: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/10.jpg)
It is mostly good stuff.
![Page 11: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/11.jpg)
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.
![Page 12: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/12.jpg)
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.
![Page 13: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/13.jpg)
Closure• The scope that an inner function
enjoys continues even after the parent functions have returned.
• This is called closure.
![Page 14: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/14.jpg)
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); }
![Page 15: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/15.jpg)
Inheritance• Inheritance is object-oriented code
reuse.
• Two Schools:
• Classical
• Prototypal
![Page 16: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/16.jpg)
Classical Inheritance• Objects are instances of Classes.
• A Class inherits from another Class.
![Page 17: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/17.jpg)
Pseudoclassical• Pseudoclassical looks sort of classical, but
is really prototypal.
• Three mechanisms:
• Constructor functions.
• The prototype member of functions.
• The new operator.
![Page 18: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/18.jpg)
Psuedoclassicalfunction Constructor() { this.member = initializer; return this; // optional}
Constructor.prototype.firstMethod = function (a, b) {...};Constructor.prototype.secondMethod = function (c) {...};
var newObject = new Constructor();
![Page 19: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/19.jpg)
new operatorvar newObject = new Constructor();
• new Constructor() returns a new object with a link to Constructor.prototype.
Constructor.prototypenewObject
![Page 20: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/20.jpg)
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.
![Page 21: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/21.jpg)
Syntactic Rat PoisonConstructor. method('first_method', function (a, b) {...}). method('second_method', function (c) {...});-----------------------------------
Function.prototype.method = function (name, func) { this.prototype[name] = func; return this; };
![Page 22: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/22.jpg)
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.
![Page 23: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/23.jpg)
Example
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
![Page 24: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/24.jpg)
Example
prototype
id string
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
constructortoString functionprototype
constructortoString function
new Gizmo(string)
Gizmo
Object
![Page 25: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/25.jpg)
Example
prototype
id string
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
constructortoString functionprototype
constructortoString function
new Gizmo(string)
Gizmo
Object
![Page 26: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/26.jpg)
Example
prototype
id string
function Gizmo(id) {
this.id = id;
}
Gizmo.prototype.toString = function () {
return "gizmo " + this.id;
};
constructortoString functionprototype
constructortoString function
new Gizmo(string)
Gizmo
Object
![Page 27: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/27.jpg)
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.
![Page 28: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/28.jpg)
Example
function Hoozit(id) {
this.id = id;
}
Hoozit.prototype = new Gizmo();
Hoozit.prototype.test = function (id) {
return this.id === id;
};
![Page 29: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/29.jpg)
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
constructortoString function
Gizmo
Hoozit
id string
new Hoozit(string)
![Page 30: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/30.jpg)
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
constructortoString function
Gizmo
Hoozit
id string
new Hoozit(string)
![Page 31: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/31.jpg)
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
![Page 32: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/32.jpg)
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.
![Page 33: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/33.jpg)
object function function object(o) { function F() {} F.prototype = o; return new F(); }
![Page 34: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/34.jpg)
object function
prototype
F
function object(o) { function F() {} F.prototype = o; return new F();
} newObject = object(oldObject)
constructor
![Page 35: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/35.jpg)
object function
prototype
F
function object(o) { function F() {} F.prototype = o; return new F();
} newObject = object(oldObject)
oldObject
constructor
![Page 36: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/36.jpg)
object function
prototype
F
newObject
function object(o) { function F() {} F.prototype = o; return new F();
} newObject = object(oldObject)
oldObject
![Page 37: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/37.jpg)
object function
newObject
function object(o) { function F() {} F.prototype = o; return new F();
} newObject = object(oldObject)
oldObject
![Page 38: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/38.jpg)
Prototypal Inheritancevar oldObject = { firstMethod: function () {...}, secondMethod: function () {...}};
var newObject = object(oldObject);
newObject.thirdMethod = function () {...};
var myDoppelganger = object(newObject);
myDoppelganger.firstMethod();
![Page 39: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/39.jpg)
Prototypal Inheritance• There is no limit to the length of the
chain (except common sense).
oldObject
myDoppelganger = object(newObject);
newObject
![Page 40: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/40.jpg)
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.
![Page 41: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/41.jpg)
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".
![Page 42: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/42.jpg)
Public MethodsmyObject.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.
![Page 43: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/43.jpg)
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.
![Page 44: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/44.jpg)
Singletonsvar singleton = { firstMethod: function (a, b) { ... }, secondMethod: function (c) { ... }};
![Page 45: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/45.jpg)
Functions are used as
• Functions• Methods• Constructors• Classes• Modules
![Page 46: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/46.jpg)
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.
![Page 47: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/47.jpg)
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.
![Page 48: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/48.jpg)
Singletons• The methods of a singleton can enjoy
access to shared private data and private methods.
![Page 49: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/49.jpg)
Singletonsvar singleton = function () { var privateVariable; function privateFunction(x) { ...privateVariable... }
return { firstMethod: function (a, b) { ...privateVariable... }, secondMethod: function (c) { ...privateFunction()... } };}();
![Page 50: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/50.jpg)
Applications are Singletonsvar AJAX = function () { var privateVariable; function privateFunction(x) { ...privateVariable... }
return { firstMethod: function (a, b) { ...privateVariable... }, secondMethod: function (c) { ...privateFunction()... } };}();
![Page 51: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/51.jpg)
Privacy• All members of an object are public.
• We want private variables and private methods.
• Really.
![Page 52: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/52.jpg)
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.
![Page 53: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/53.jpg)
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.
![Page 54: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/54.jpg)
Power Constructorfunction powerConstructor() { var that = object(oldObject), privateVariable; function privateFunction(x) { ... }
that.firstMethod = function (a, b) { ...privateVariable... }; that.secondMethod = function (c) { ...privateFunction()... }; return that;}
![Page 55: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/55.jpg)
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();
![Page 56: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/56.jpg)
Parasitic Inheritance• A power constructor calls another
constructor, takes the result, augments it, and returns it as though it did all the work.
![Page 57: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/57.jpg)
Psudeoclassical Inheritancefunction 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;}
![Page 58: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/58.jpg)
Parasitic Inheritancefunction 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;}
![Page 59: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/59.jpg)
Secretsfunction gizmo(id) { return { toString: function () { return "gizmo " + id; } };}
function hoozit(id) { var that = gizmo(id); that.test = function (testid) { return testid === id; }; return that;}
![Page 60: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/60.jpg)
Shared Secretsfunction 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;}
![Page 61: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/61.jpg)
Super Methodsfunction 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;}
![Page 62: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/62.jpg)
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.
![Page 63: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/63.jpg)
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.
![Page 64: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/64.jpg)
Performance• Provide a good experience.
• Be respectful of our customer's time.
• Hoare's Dictum: Premature optimization is the root of all evil.
![Page 65: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/65.jpg)
Efficiency• The first priority must always be
correctness.
• Optimize when necessary.
• Consider algorithmic improvements O (n) v O (n log n) v O (n2)
• Watch for limits.
![Page 66: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/66.jpg)
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
![Page 67: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/67.jpg)
Code Conventions for the JavaScript Programming
Language
http://javascript.crockford.com/code.html
![Page 68: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/68.jpg)
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.
![Page 69: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/69.jpg)
JSLint• Warning: JSLint will hurt your
feelings.
• If you follow its advice, JSLint will make your programs better.
•http://www.JSLint.com/
![Page 70: Ajax World](https://reader035.fdocuments.net/reader035/viewer/2022070508/577cc7781a28aba711a109de/html5/thumbnails/70.jpg)
JavaScript:A Language of Many Contrasts
Douglas CrockfordYahoo!
http://javascript.crockford.com/ajaxworld.ppt