Initial commit

parents
## Example files for the title:
# JavaScript: The Good Parts, by Douglas Crockford
[![JavaScript: The Good Parts, by Douglas Crockford](http://akamaicovers.oreilly.com/images/9780596517748/cat.gif)](https://www.safaribooksonline.com/library/view/title/9780596517748//)
The following applies to example files from material published by O’Reilly Media, Inc. Content from other publishers may include different rules of usage. Please refer to any additional usage rights explained in the actual example files or refer to the publisher’s website.
O'Reilly books are here to help you get your job done. In general, you may use the code in O'Reilly books in your programs and documentation. You do not need to contact us for permission unless you're reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from our books does not require permission. Answering a question by citing our books and quoting example code does not require permission. On the other hand, selling or distributing a CD-ROM of examples from O'Reilly books does require permission. Incorporating a significant amount of example code from our books into your product's documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN.
If you think your use of code examples falls outside fair use or the permission given here, feel free to contact us at <permissions@oreilly.com>.
Please note that the examples are not production code and have not been carefully testing. They are provided "as-is" and come with no warranty of any kind.
appendix: Awful Parts
==================
var foo = value;
====================================
window.foo = value;
====================================
foo = value;
====================================
return
{
status: true
};
====================================
return {
status: true
};
====================================
abstract boolean break byte case catch char class const continue
debugger default delete do double else enum export extends false final
finally float for
function goto if implements import in instanceof int interface long native new null
package private protected public return short static super switch synchronized this
throw throws transient true try typeof var volatile void while with
====================================
var method; // ok
var class; // illegal
object = {box: value}; // ok
object = {case: value}; // illegal
object = {'case': value}; // ok
object.box = value; // ok
object.case = value; // illegal
object['case'] = value; // ok
====================================
typeof 98.6
====================================
typeof null
====================================
my_value === null
====================================
if (my_value && typeof my_value === 'object') {
// my_value is an object or an array!
}
====================================
typeof /a/
====================================
typeof NaN === 'number' // true
====================================
+ '0' // 0
+ 'oops' // NaN
====================================
NaN === NaN // false
NaN !== NaN // true
====================================
isNaN(NaN) // true
isNaN(0) // false
isNaN('oops') // true
isNaN('0') // false
====================================
var isNumber = function isNumber(value) {
return typeof value === 'number' && isFinite(value);
};
====================================
if (Object.prototype.toString.apply(my_value) === '[object Array]'){
// my_value is truly an array!
}
====================================
if (my_value && typeof my_value === 'object' &&
typeof my_value.length === 'number' &&
!(my_value.propertyIsEnumerable('length')) {
// my_value is truly an array!
}
====================================
value = myObject[name];
if (value == null) {
alert(name + ' not found.');
}
====================================
var name;
another_stooge.hasOwnProperty = null; // trouble
for (name in another_stooge) {
if (another_stooge.hasOwnProperty(name)) { // boom
document.writeln(name + ': ' + another_stooge[name]);
}
}
====================================
var i;
var word;
var text =
"This oracle of comfort has so pleased me, " +
"That when I am in heaven I shall desire " +
"To see what this child does, " +
"and praise my Constructor.";
var words = text.toLowerCase( ).split(/[\s,.]+/);
var count = {};
for (i = 0; i < words.length; i += 1) {
word = words[i];
if (count[word]) {
count[word] += 1;
} else {
count[word] = 1;
}
}
====================================
if (typeof count[word] === 'number') {
==================
\ No newline at end of file
appendix: Bad Parts
==================
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
====================================
with (obj) {
a = b;
}
====================================
if (obj.a === undefined) {
a = obj.b === undefined ? b : obj.b;
} else {
obj.a = obj.b === undefined ? b : obj.b;
}
====================================
a = b;
a = obj.b;
obj.a = b;
obj.a = obj.b;
====================================
eval("myValue = myObject." + myKey + ";");
====================================
myvalue = myObject[myKey];
====================================
if (ok)
t = true;
====================================
if (ok)
t = true;
advance( );
====================================
if (ok) {
t = true;
advance( );
}
====================================
if (ok) {
t = true;
}
advance( );
====================================
for (p = src, q = dest; !*p; p++, q++) *q = *p;
====================================
& and
| or
^ xor
˜ not
>> signed right shift
>>> unsigned right shift
<< left shift
====================================
function foo( ) {}
====================================
var foo = function foo( ) {};
====================================
(function ( ) {
var hidden_variable;
// This function can have some impact on
// the environment, but introduces no new
// global variables.
}());
====================================
new Boolean(false)
==================
\ No newline at end of file
appendix: JSLint
==================
/*global getElementByAttribute, breakCycles, hanoi */
====================================
/*members doTell, iDoDeclare, mercySakes,
myGoodness, ohGoOn, wellShutMyMouth */
====================================
/*jslint nomen: true, evil: false */
====================================
, ; : { } ( [ = < > ? ! + - * / % ˜ ^ | &
== != <= >= += -= *= /= %= ^= |= &= << >> || &&
=== !== <<= >>= >>> >>>=
====================================
) ] . ++ --
====================================
if (condition)
statement;
====================================
if (condition) {
statements;
}
====================================
for (name in object) {
if (object.hasOwnProperty(name)) {
....
}
}
====================================
if (a = b) {
...
}
====================================
if (a == b) {
...
}
====================================
0 '' undefined null false true
====================================
(foo != 0)
====================================
(foo)
====================================
(foo == 0)
====================================
(!foo)
==================
\ No newline at end of file
appendix: JSON
==================
[
{
"first": "Jerome",
"middle": "Lester",
"last": "Howard",
"nick-name": "Curly",
"born": 1903,
"died": 1952,
"quote": "nyuk-nyuk-nyuk!"
},
{
"first": "Harry",
"middle": "Moses",
"last": "Howard",
"nick-name": "Moe",
"born": 1897,
"died": 1975,
"quote": "Why, you!"
},
{
"first": "Louis",
"last": "Feinberg",
"nick-name": "Larry",
"born": 1902,
"died": 1975,
"quote": "I'm sorry. Moe, it was an accident!"
}
]
====================================
var myData = eval('(' + myJSONText + ')');
====================================
var json_parse = function () {
// This is a function that can parse a JSON text, producing a JavaScript
// data structure. It is a simple, recursive descent parser.
// We are defining the function inside of another function to avoid creating
// global variables.
var at, // The index of the current character
ch, // The current character
escapee = {
'"': '"',
'\\': '\\',
'/': '/',
b: 'b',
f: '\f',
n: '\n',
r: '\r',
t: '\t'
},
text,
error = function (m) {
// Call error when something is wrong.
throw {
name: 'SyntaxError',
message: m,
at: at,
text: text
};
},
next = function (c) {
// If a c parameter is provided, verify that it matches the current character.
if (c && c !== ch) {
error("Expected '" + c + "' instead of '" + ch + "'");
}
// Get the next character. When there are no more characters,
// return the empty string.
ch = text.charAt(at);
at += 1;
return ch;
},
number = function () {
// Parse a number value.
var number,
string = '';
if (ch === '-') {
string = '-';
next('-');
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
if (ch === '.') {
string += '.';
while (next() && ch >= '0' && ch <= '9') {
string += ch;
}
}
if (ch === 'e' || ch === 'E') {
string += ch;
next();
if (ch === '-' || ch === '+') {
string += ch;
next();
}
while (ch >= '0' && ch <= '9') {
string += ch;
next();
}
}
number = +string;
if (isNaN(number)) {
error("Bad number");
} else {
return number;
}
},
string = function () {
// Parse a string value.
var hex,
i,
string = '',
uffff;
// When parsing for string values, we must look for " and \ characters.
if (ch === '"') {
while (next()) {
if (ch === '"') {
next();
return string;
} else if (ch === '\\') {
next();
if (ch === 'u') {
uffff = 0;
for (i = 0; i < 4; i += 1) {
hex = parseInt(next(), 16);
if (!isFinite(hex)) {
break;
}
uffff = uffff * 16 + hex;
}
string += String.fromCharCode(uffff);
} else if (typeof escapee[ch] === 'string') {
string += escapee[ch];
} else {
break;
}
} else {
string += ch;
}
}
}
error("Bad string");
},
white = function () {
// Skip whitespace.
while (ch && ch <= ' ') {
next();
}
},
word = function () {
// true, false, or null.
switch (ch) {
case 't':
next('t');
next('r');
next('u');
next('e');
return true;
case 'f':
next('f');
next('a');
next('l');
next('s');
next('e');
return false;
case 'n':
next('n');
next('u');
next('l');
next('l');
return null;
}
error("Unexpected '" + ch + "'");
},
value, // Place holder for the value function.
array = function () {
// Parse an array value.
var array = [];
if (ch === '[') {
next('[');
white();
if (ch === ']') {
next(']');
return array; // empty array
}
while (ch) {
array.push(value());
white();
if (ch === ']') {
next(']');
return array;
}
next(',');
white();
}
}
error("Bad array");
},
object = function () {
// Parse an object value.
var key,
object = {};
if (ch === '{') {
next('{');
white();
if (ch === '}') {
next('}');
return object; // empty object
}
while (ch) {
key = string();
white();
next(':');
object[key] = value();
white();
if (ch === '}') {
next('}');
return object;
}
next(',');
white();
}
}
error("Bad object");
};
value = function () {
// Parse a JSON value. It could be an object, an array, a string, a number,
// or a word.
white();
switch (ch) {
case '{':
return object();
case '[':
return array();
case '"':
return string();
case '-':
return number();
default:
return ch >= '0' && ch <= '9' ? number() : word();
}
};
// Return the json_parse function. It will have access to all of the above
// functions and variables.
return function (source, reviver) {
var result;
text = source;
at = 0;
ch = ' ';
result = value();
white();
if (ch) {
error("Syntax error");
}
// If there is a reviver function, we recursively walk the new structure,
// passing each name/value pair to the reviver function for possible
// transformation, starting with a temporary boot object that holds the result
// in an empty key. If there is not a reviver function, we simply return the
// result.
return typeof reviver === 'function' ?
function walk(holder, key) {
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}({'': result}, '') : result;
};
}();
==================
\ No newline at end of file
chapter: Good Parts
==================
<html><body><pre><script src="program.js">
</script></pre></body></html>
====================================
document.writeln('Hello, world!');
====================================
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
==================
\ No newline at end of file
chapter: Grammar
==================
var that = this;
====================================
/*
var rm_a = /a*/.match(s);
*/
====================================
abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface
long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with
====================================
"A" === "\u0041"
====================================
'c' + 'a' + 't' === 'cat'
====================================
'cat'.toUpperCase( ) === 'CAT'
====================================
for (myvar in obj) {
if (obj.hasOwnProperty(myvar)) {
...
}
}
====================================
2 + 3 * 5 === 17
(2 + 3) * 5 === 25
==================
\ No newline at end of file
chapter: Objects
==================
var empty_object = {};
var stooge = {
"first-name": "Jerome",
"last-name": "Howard"
};
====================================
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
====================================
stooge["first-name"] // "Jerome"
flight.departure.IATA // "SYD"
====================================
stooge["middle-name"] // undefined
flight.status // undefined
stooge["FIRST-NAME"] // undefined
====================================
var middle = stooge["middle-name"] || "(none)";
var status = flight.status || "unknown";
====================================
flight.equipment // undefined
flight.equipment.model // throw "TypeError"
flight.equipment && flight.equipment.model // undefined
====================================
stooge['first-name'] = 'Jerome';
====================================
stooge['middle-name'] = 'Lester';
stooge.nickname = 'Curly';
flight.equipment = {
model: 'Boeing 777'
};
flight.status = 'overdue';
====================================
var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname;
// nick is 'Curly' because x and stooge
// are references to the same object
var a = {}, b = {}, c = {};
// a, b, and c each refer to a
// different empty object
a = b = c = {};
// a, b, and c all refer to
// the same empty object
====================================
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
var another_stooge = Object.create(stooge);
====================================
another_stooge['first-name'] = 'Harry';
another_stooge['middle-name'] = 'Moses';
another_stooge.nickname = 'Moe';
====================================
stooge.profession = 'actor';
another_stooge.profession // 'actor'
====================================
typeof flight.number // 'number'
typeof flight.status // 'string'
typeof flight.arrival // 'object'
typeof flight.manifest // 'undefined'
====================================
typeof flight.toString // 'function'
typeof flight.constructor // 'function'
====================================
flight.hasOwnProperty('number') // true
flight.hasOwnProperty('constructor') // false
====================================
var name;
for (name in another_stooge) {
if (typeof another_stooge[name] !== 'function') {
document.writeln(name + ': ' + another_stooge[name]);
}
}
====================================
var i;
var properties = [
'first-name',
'middle-name',
'last-name',
'profession'
];
for (i = 0; i < properties.length; i += 1) {
document.writeln(properties[i] + ': ' +
another_stooge[properties[i]]);
}
====================================
another_stooge.nickname // 'Moe'
// Remove nickname from another_stooge, revealing
// the nickname of the prototype.
delete another_stooge.nickname;
another_stooge.nickname // 'Curly'
====================================
var MYAPP = {};
====================================
MYAPP.stooge = {
"first-name": "Joe",
"last-name": "Howard"
};
MYAPP.flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
==================
\ No newline at end of file
chapter: Inheritance
==================
this.prototype = {constructor: this};
====================================
Function.method('new', function ( ) {
// Create a new object that inherits from the
// constructor's prototype.
var that = Object.beget(this.prototype);
// Invoke the constructor, binding -this- to
// the new object.
var other = this.apply(that, arguments);
// If its return value isn't an object,
// substitute the new object.
return (typeof other === 'object' && other) || that;
});
====================================
var Mammal = function (name) {
this.name = name;
};
Mammal.prototype.get_name = function ( ) {
return this.name;
};