Skip to content

HugoMatilla/JavaScriptTheGoodParts-Summary

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 

Repository files navigation

This is my summary of the (JavaScript: The Good Parts By Douglas Crockford)[http://shop.oreilly.com/product/9780596517748.do]. I use it while learning and as quick reference. It is not intended to be an standalone substitution of the book so if you really want to learn the concepts here presented, buy and read the book and use this repository as a reference and guide.

If you are the publisher and think this repository should not be public, just write me an email at hugomatilla [at] gmail [dot] com and I will make it private.

Contributions: Issues, comments and pull requests are super welcome 😃

1.Table of Contents

2.Grammar

White Space

alt text

Name

Names are used for statements, variables, parameters, property names, operators, and labels. alt text

Reserved Words

abstract else instanceof super
boolean enum int switch
break export interface synchronized
byte extends let this
case FALSE long throw
catch final native throws
char finally new transient
class float null TRUE
const for package try
continue function private typeof
debugger goto protected var
default if public void
delete implements return volatile
do import short while
double in static with

Avoid also these ones

alert frames outerHeight
all frameRate outerWidth
anchor function packages
anchors getClass pageXOffset
area hasOwnProperty pageYOffset
Array hidden parent
assign history parseFloat
blur image parseInt
button images password
checkbox Infinity pkcs11
clearInterval isFinite plugin
clearTimeout isNaN prompt
clientInformation isPrototypeOf propertyIsEnum
close java prototype
closed JavaArray radio
confirm JavaClass reset
constructor JavaObject screenX
crypto JavaPackage screenY
Date innerHeight scroll
decodeURI innerWidth secure
decodeURIComponent layer select
defaultStatus layers self
document length setInterval
element link setTimeout
elements location status
embed Math String
embeds mimeTypes submit
encodeURI name taint
encodeURIComponent NaN text
escape navigate textarea
eval navigator top
event Number toString
fileUpload Object undefined
focus offscreenBuffering unescape
form open untaint
forms opener valueOf
frame option window

And these

onbeforeunload ondragdrop onkeyup onmouseover
onblur onerror onload onmouseup
ondragdrop onfocus onmousedown onreset
onclick onkeydown onmousemove onsubmit
oncontextmenu onkeypress onmouseout onunload

Numbers

Only one number type. 64-bit floating point. (Java double)

NaN is a number of an operation that cannot produce a normal result. Use isNaN(number) to detect it.

Infinity represents all values greater than 1.79769313486231570e+308.

alt text alt text alt text alt text

Strings

Strings can be wrapped in single quotes or double quotes. The \ (backslash) is the escape character. Characters in JavaScript are 16 bits wide.

alt text

Escape sequences allow for inserting characters into strings that are not normally permitted alt text

Strings have a length property

Strings are immutable.

Statements

var Statements

A compilation unit contains a set of executable statements. alt text

Statements

alt text

Disruptive Statements

alt text

Block

Blocks in JavaScript do not create a new scope, so variables should be defined at the top of the function, not in blocks. alt text

If Statement

alt text False values:

  • false
  • null
  • undefined
  • The empty string ''
  • The number 0
  • The number NaN All other values are truthy, including true, the string 'false', and all objects.

Swith Statements

alt text

Case Clause

alt text

While Statement

alt text

For Statement

alt text

Do Statement

alt text

Try Statement

alt text

Throw Statement

alt text

Return Statement

alt text

Break Statement

alt text

Expression Statement

alt text

Expressions

alt text

The simplest expressions are:

  • a literal value (such as a string or number)
  • a variable
  • a built-in value (true, false, null, undefined, NaN, or Infinity)
  • an invocation expression preceded by new
  • a refinement expression preceded by delete
  • an expression wrapped in parentheses
  • an expression preceded by a prefix operator
  • an expression followed by:
    • An infix operator and another expression
    • The ? ternary operator followed by another expression, then by :, and then byyet another expression
    • An invocation
    • A refinement

#Operands precedence

| . [] ( ) | Refinement and invocation | | delete new typeof + - ! | Unary operators | | * / % | Multiplication, division, modulo | | + - | Addition/concatenation, subtraction | | >= <= > < | Inequality | | === !== | Equality | | && | Logical and | | || | Logical or | | ?: | Ternary |

Prefix Operator

alt text

The values produced by typeof are 'number', 'string', 'boolean', 'undefined','function', and 'object'. If the operand is an array or null, then the result is 'object', which is wrong.

The + operator adds or concatenates. If you want it to add, make sure both operands are numbers.

The / operator can produce a noninteger result even if both operands are integers.

Infix operator

alt text

Invoaction

Invocation causes the execution of a function value. alt text

Refinement

Specify a property or element of an object or array alt text

Literals

alt text

Object Literal

alt text

Regex Literal

alt text

Functions

Function Literal

alt text A function literal defines a function value.

It can have an optional name that it can use to call itself recursively.

Parameters

alt text

Function body

alt text

3.Objects

Numbers, strings, and booleans are not objects the rest are.

Numbers, strings, and booleans are object-like in that they have methods, but they are immutable.

Objects in JavaScript are mutable keyed collections.

An object is a container of properties, where a property has a name and a value.

  • A property name can be any string, including the empty string.
  • A property value can be any JavaScript value except for undefined.

Objects in JavaScript are class-free.

JavaScript includes a prototype linkage feature that allows one object to inherit the properties of another.

Object Literals

An object literal is a pair of curly braces surrounding zero or more name/value pairs.

	var empty_object = {};

	var stooge = {
		"first-name": "Jerome",
		"last-name": "Howard"
	};

Retrieval

Values can be retrieved from an object by wrapping a string expression in a [ ] suffix.

Dot . notation can be use if the string expression is a constant, legal and not a reserved word.

undefined value is produced if an attempt is made to retrieve a nonexistent member.

	stooge.middle-name //undefined

|| can be used to fill default values

	var middle = stooge["middle-name"] || "(none)";

&& to avoid TypeError exception when retrieving values from undefined

	flight.equipment // undefined
	flight.equipment.model // throw "TypeError"
	flight.equipment && flight.equipment.model // undefined

Update

Updated by assignment. If exists it changes if not it is added.

	stooge['first-name'] = 'Jerome';

Reference

Objects are passed around by reference. They are never copied

Prototype

Every object is linked to a prototype object from which it can inherit properties.

All Objects are linked to Object.prototype, an object that comes standard with JavaScript.

When you make a new object, you can select the object that should be its prototype.

Reflection

Use typeof to determine what properties an object has.

hasOwnProperty method, which returns true if the object has a particular property. It does not look at the prototype chain

	flight.hasOwnProperty('number') // true
	flight.hasOwnProperty('constructor') // false

Enumeration

The for in statement can loop over all of the property names in an object, including functions and prototype properties that you might not be interested.

Filter them using typeof. The order will not be guaranteed

	var name;
	for (name in another_stooge) {
		if (typeof another_stooge[name] !== 'function') {
			document.writeln(name + ': ' + another_stooge[name]);
		}
	}

Delete

delete removes a property from an object.

Global Abatement

JavaScript makes it easy to define global variables but they weaken the resiliency of programs and should be avoided.

Create a single global variable for your application:

	var MYAPP = {};
	MYAPP.stooge = {
		"first-name": "Joe",
		"last-name": "Howard"
	};
	MYAPP.flight = {
		airline: "Oceanic",
		number: 815,
		...
	};

By reducing your global footprint to a single name, you significantly reduce the chance of bad interactions with other applications, widgets, or libraries.

4.Functions

Function Objects

  • Functions are objects.
  • Objects are collections of name/value pairs.
  • Objects have a hidden link to a prototype object.
  • Objects produced from object literals are linked to Object.prototype.
  • Function objects are linked to Function.prototype (which is linked to Object.prototype)
  • Every function is created with two additional hidden properties: *the function’s context *the code that implements the function’s behavior.
  • Every function object is created with a prototype property. Its value is an object with a constructor property whose value is the function. This is distinct from the hidden link to Function.prototype.
  • Functions (because they are objects) can be:
    • stored in variables, objects, and arrays.
    • passed as arguments to functions
    • returned from functions.
    • have methods.

The special thing about functions is that they can be invoked.

Function Literals

Function objects are created with function literals:

	var add = function (a, b) {
		return a + b;
	};

A function literal has four parts:

    1. reserved word function.
    1. The optional function’s name. If no name, it is called anonymous function.
    1. Set of parameters wrapped in parentheses.
    1. A set of statements wrapped in curly braces. These statements are the body of the function. They are executed when the function is invoked.

Closure A link to the outer function context.

Invocation

Invoking a function suspends the execution of the current function, passing control and parameters to the new function. In addition to the declared parameters, every function receives two additional parameters: this and arguments.

this:is determined by the invocation pattern. There are four patterns of invocation in JavaScript:

  • the method invocation pattern,
  • the function invocation pattern,
  • the constructor invocation pattern,
  • the apply invocation pattern.

The patterns differ in how the bonus parameter this is initialized.

The Method Invocation Pattern

When a function is stored as a property of an object, we call it a method.

When a method is invoked, this is bound to that object. If an invocation expression contains a refinement (that is, a . dot expression or [subscript] expression), it is invoked as a method:

	myObject.increment(2);

The binding of this to the object happens at invocation time.

Methods that get their object context from this are called public methods.

The Function Invocation Pattern

When a function is not the property of an object, then it is invoked as a function:

	var sum = add(3, 4); // sum is 7

When a function is invoked with this pattern, this is bound to the global object. It should be to the outer function.

Defining a variable and assigns it the value of this will make the trick.

By convention, the name of that variable is that:

	// Augment myObject with a double method.
	myObject.double = function ( ) {
		var that = this; // Workaround.
		var helper = function ( ) {
			that.value = add(that.value, that.value);
		};
		helper( ); // Invoke helper as a function.
	};

The Constructor Invocation Pattern

If a function is invoked with the new prefix, then a new object will be created with a hidden link to the value of the function’s prototype member, and this will be bound to that new object.

Use of this style of constructor functions is not recommended.

	var Quo = function (string) {
		this.status = string;
	}	
	
	Quo.prototype.get_status = function ( ) {
		return this.status;
	}

	var myQuo = new Quo("confused");
	document.writeln(myQuo.get_status( )); // confused

The Apply Invocation Pattern

Functions can have methods.

The apply method lets us construct an array of arguments to use to invoke a function.

It also lets us choose the value of this.

The apply method takes two parameters.

The first is the value that should be bound to this.

The second is an array of parameters.

	var array = [3, 4];
	var sum = add.apply(null, array); // sum is 7
	
	var statusObject = {
		status: 'A-OK'
	};
	// statusObject does not inherit from Quo.prototype,
	// but we can invoke the get_status method on
	// statusObject even though statusObject does not have
	// a get_status method.
	var status = Quo.prototype.get_status.apply(statusObject);
	// status is 'A-OK'

Arguments

A bonus parameter that is available to functions when they are invoked is the arguments array. It gives the function access to all of the arguments that were supplied with the invocation, including excess arguments that were not assigned to parameters.

	var sum = function ( ) {
		var i, sum = 0;
		for (i = 0; i < arguments.length; i += 1) {
		sum += arguments[i];
	}
		return sum;
	};
	document.writeln(sum(4, 8, 15, 16, 23, 42)); // 108

arguments is not really an array. It is an array-like object.arguments has a length property, but it lacks all of the array methods.

Return

When a function is invoked, it begins execution with the first statement, and ends when it hits the } that closes the function body.

That causes the function to return control to the part of the program that invoked the function.

The return statement can be used to cause the function to return early. When return is executed, the function returns immediately without executing the remaining statements.

A function always returns a value. If the return value is not specified, then undefined is returned.

If the function was invoked with the new prefix and the return value is not an object, then this (the new object) is returned instead

Exceptions

		if (typeof a !== 'number' || typeof b !== 'number') {
			throw {
				name: 'TypeError',
				message: 'add needs numbers'
			};
		}
		return a + b;
	}

The throw statement interrupts execution of the function.

It should be given an exception object containing a name and message. The exception object will be delivered to the catch clause of a try statement:

	var try_it = function ( ) {
		try {
			add("seven");
		} catch (e) {
			document.writeln(e.name + ': ' + e.message);
		}
	}
	try_it( );

A try statement has a single catch block that will catch all exceptions.

The exception handler will have to inspect the name to determine the type of the exception.

Augmenting Types

JavaScript allows the basic types of the language to be augmented.

For example, by augmenting Function.prototype, we can make a method available to all functions:

	Function.prototype.method = function (name, func) {
		this.prototype[name] = func;
		return this;
	};
	Number.method('integer', function ( ) {
		return Math[this < 0 ? 'ceiling' : 'floor'](this);
	});
	document.writeln((-10 / 3).integer( )); // -3

The prototypes of the basic types are public structures, so care must be taken when mixing libraries. One defensive technique is to add a method only if the method is known to be missing:

	Function.prototype.method = function (name, func) {
		if (!this.prototype[name]) {
		this.prototype[name] = func;
		}
	};

Recursion

A recursive function is a function that calls itself, either directly or indirectly.

Recursion is a powerful programming technique in which a problem is divided into a set of similar subproblems, each solved with a trivial solution.

Scope

Scope in a programming language controls the visibility and lifetimes of variables and parameters.

	var foo = function ( ) {
		var a = 3, b = 5;
		var bar = function ( ) {
	
			var b = 7, c = 11;
			// At this point, a is 3, b is 7, and c is 11
	
			a += b + c;
			// At this point, a is 21, b is 7, and c is 11
		};
		// At this point, a is 3, b is 5, and c is not defined
	
		bar( );
		// At this point, a is 21, b is 5
	};

JavaScript does not have block scope.

JavaScript does have function scope. The parameters and variables defined in a function are not visible outside of the function, and that a variable defined anywhere within a function is visible everywhere within the function

Closure

The good news about scope is that inner functions get access to the parameters and variables of the functions they are defined within (with the exception of this and arguments). This is a very good thing.

	var quo = function (status) {
	  return {
	    get_status: function ( ) {
	      return status;
	    }
	  };
	};
	// Make an instance of quo.

	var myQuo = quo("amazed");

	console.log(myQuo.get_status( ));

When we call quo, it returns a new object containing a get_status method.

A reference to that object is stored in myQuo.

The get_status method still has privileged access to quo’s status property even though quo has already returned.

get_status does not have access to a copy of the parameter; it has access to the parameter itself.

This is possible because the function has access to the context in which it was created. This is called closure.

Callbacks

Functions can make it easier to deal with discontinuous events.

	request = prepare_the_request( );
	send_request_asynchronously(request, function (response) {
		display(response);
	});

We pass a function parameter to the send_request_asynchronously function that will be called when the response is available.

Module

A module is a function or object that presents an interface but that hides its state and implementation.

By using functions to produce modules, we can almost completely eliminate our use of global variables, thereby mitigating one of JavaScript’s worst features.

The module pattern takes advantage of function scope and closure to create relationships that are binding and private. In this example, only the deentityify method has access to the entity data structure.

The general pattern of a module is a function that defines private variables and functions; creates privileged functions which, through closure, will have access to the private variables and functions; and that returns the privileged functions or stores them in an accessible place.

Use of the module pattern can eliminate the use of global variables. It promotes information hiding and other good designs practices.

	var serial_maker = function ( ) {
		var prefix = '';
		var seq = 0;
		return {
			set_prefix: function (p) {
				prefix = String(p);
			},
			set_seq: function (s) {
				seq = s;
			},
			gensym: function ( ) {
				var result = prefix + seq;
				seq += 1;
				return result;
			}
		};
	};
	var seqer = serial_maker( );
	seqer.set_prefix = ('Q';)
	seqer.set_seq = (1000);
	var unique = seqer.gensym( ); // unique is "Q1000"

The methods do not make use of this or that. As a result, there is no way to compromise the seqer.

It isn’t possible to get or change the prefix or seq except as permitted by the methods.

The seqer object is mutable, so the methods could be replaced, but that still does not give access to its secrets.

seqer is simply a collection of functions, and those functions are capabilities that grant specific powers to use or modify the secret state.

If we passed seqer.gensym to a third party’s function, that function would be able to generate unique strings, but would be unable to change the prefix or seq.

Cascade

Some methods do not have a return value.

If we have those methods return this instead of undefined, we can enable cascades.

	getElement('myBoxDiv').
		move(350, 150).
		width(100).
		height(100).
		color('red').
		border('10px outset')

Curry

Functions are values, and we can manipulate function values in interesting ways.

Currying allows us to produce a new function by combining a function and an argument:

	var add1 = add.curry(1);
	document.writeln(add1(6)); //7

JavaScript does not have a curry method, but we can fix that by augmenting Function.prototype:

	Function.method('curry', function ( ) {
		var slice = Array.prototype.slice,
		args = slice.apply(arguments),
		that = this;
		return function ( ) {
			return that.apply(null, args.concat(slice.apply(arguments)));
		};
	});

Memoization

Functions can use objects to remember the results of previous operations, making it possible to avoid unnecessary work.

This optimization is called memoization.

We will keep our memoized results in a memo array that we can hide in a closure.

When our function is called, it first looks to see if it already knows the result.

If it does, it can immediately return it:

	var fibonacci = function ( ) {
		var memo = [0, 1];
		var fib = function (n) {
			var result = memo[n];
			if (typeof result !== 'number') {
				result = fib(n - 1) + fib(n - 2);
				memo[n] = result;
			}
			return result;
		};
		return fib;
	}( );

A generalized version:

	var memoizer = function (memo, fundamental) {
		var shell = function (n) {
			var result = memo[n];
			if (typeof result !== 'number') {
				result = fundamental(shell, n);
				memo[n] = result;
			}
			return result;
		};
	return shell;
	};	
	var fibonacci = memoizer([0, 1], function (shell, n) {
		return shell(n - 1) + shell(n - 2);
	});

5. Inheritance

In classical languages, objects are instances of classes, and a class can inherit from another class. JavaScript is a prototypal language, which means that objects inherit directly from other objects.

Pseudo Classical

A much better alternative is to not use new at all.

The pseudoclassical form can provide comfort to programmers who are unfamiliar

The classically inspired notation can induce programmers to compose hierarchies that are unnecessarily deep and complicated.

Much of the complexity of class hierarchies is motivated by the constraints of static type checking. JavaScript is completely free of those constraints.

Object Specifiers

Use makers when having a lot of arguments in the constructor of an object.

So, instead of:

	var myObject = maker(f, l, m, c, s);

we can write:

	var myObject = maker({
		first: f,
		last: l,
		state: s,
		city: c
	});

We could also use a JSON with all the parameters as the argument.

Prototypal

Contrary to purely prototypal pattern, where we dispense with classes, in JavaScript we focus on the objects.

A new object can inherit the properties of an old object.

	var myMammal = {
		name : 'Herb the Mammal',
		get_name : function ( ) {
			return this.name;
		},
		says : function ( ) {
			return this.saying || '';
		}
	};

Using create from Chapter 3

	var myCat = Object.create(myMammal);
	myCat.name = 'Henrietta';
	myCat.saying = 'meow';
	myCat.purr = function (n) {
		var i, s = '';
		for (i = 0; i < n; i += 1) {
			if (s) {
				s += '-';
			}
			s += 'r';
		}
		return s;
	};
	myCat.get_name = function ( ) {
		return this.says( ) + ' ' + this.name + ' ' + this.says( );
	};

This is differential inheritance. By customizing a new object, we specify the differences from the object on which it is based.

Functional

One weakness of the inheritance patterns we have seen so far is that we get no privacy.

We make a function that will produce objects. It contains four steps:

  1. It creates a new object. There are lots of ways to make an object.
  2. It optionally defines private instance variables and methods. These are just ordinary vars of the function.
  3. It augments that new object with methods. Those methods will have privileged access to the parameters and the vars defined in the second step.
  4. It returns that new object.
	var constructor = function (spec, my) {
		var that, other private instance variables;
		
		my = my || {};
		// Add shared variables and functions to my
		
		that = a new object;
		//Add privileged methods to that
		
		return that;
	};
  1. The spec object contains all of the information that the constructor needs to make an instance.
  2. The my object is a container of secrets that are shared by the constructors in the inheritance chain.
  3. Declare the private instance variables and private methods for the object. This is done by simply declaring variables.
  4. Add the shared secrets to the my object.
  5. Make a new object and assign it to that.
  6. Augment that, adding the privileged methods that make up the object’s interface.
	var methodical = function ( ) {
		...
	};
	that.methodical = methodical;
  1. Return that

Sample

The name and saying properties are now completely private. They are accessible only via the privileged get_name and says methods:

	var mammal = function (spec) {
		var that = {};
		that.get_name = function ( ) {
			return spec.name;
		};
		that.says = function ( ) {
			return spec.saying || '';
		};
		
		return that;
	};
	
	var myMammal = mammal({name: 'Herb'});
	var cat = function (spec) {
		spec.saying = spec.saying || 'meow';
		var that = mammal(spec);
		
		that.purr = function (n) {
			return 'r'.repeat(n);
		};
		
		that.get_name = function ( ) {
			return that.says( ) + ' ' + spec.name + ' ' + that.says( );
		};
		
		return that;
	};
	
	var myCat = cat({name: 'Henrietta'});

The functional pattern also gives us a way to deal with super methods.

Make a superior method that takes a method name and returns a function that invokes that method.

	Object.method('superior', function (name) {
		var that = this,
		method = that[name];
		return function ( ) {
			return method.apply(that, arguments);
			};
	});
	var coolcat = function (spec) {
		var that = cat(spec),
		super_get_name = that.superior('get_name');
		
		that.get_name = function (n) {
			return 'like ' + super_get_name( ) + ' baby';
		};

		return that;
	};

	var myCoolCat = coolcat({name: 'Bix'});
	var name = myCoolCat.get_name( );
	// 'like meow Bix meow baby'

The functional pattern has a great deal of flexibility.

Gives us better encapsulation and information hiding and access to super methods.

6 Arrays

Array Literals

Array literals provide a very convenient notation for creating new array values.

An array literal is a pair of square brackets surrounding zero or more values separated by commas.

Elements of an array are NOT required to be of the same type.

	var empty = [];
	var numbers = [
		'zero', 'one', 'two', 'three', 'four',
		'five', 'six', 'seven', 'eight', 'nine'
	];
	empty[1] // undefined
	numbers[1] // 'one'
	empty.length // 0
	numbers.length // 10
	var misc = [
		'string', 98.6, true, false, null, undefined,
		['nested', 'array'], {object: true}, NaN];

Length

Every array has a length property.

JavaScript’s array length is not an upper bound.

There is no array bounds error.

The length property is the largest integer property name in the array plus one.

This is not necessarily the number of properties in the array:

	var myArray = [];
	myArray.length // 0
	myArray[1000000] = true;
	myArray.length // 1000001
	// myArray contains one property.

The length can be set explicitly.

Making the length larger does not allocate more space for the array.

Making the length smaller will delete elements.

	numbers.length = 3;
	// numbers is ['zero', 'one', 'two']

A new element can be appended to the end of an array by assigning to the array’s current length:

	numbers[numbers.length] = 'shi';
	// numbers is ['zero', 'one', 'two', 'shi']

Use push for that

	numbers.push('go');
	// numbers is ['zero', 'one', 'two', 'shi', 'go']

Delete

Since JavaScript’s arrays are really objects, the delete operator can be used to remove elements from an array:

	delete numbers[2];
	// numbers is ['zero', 'one', undefined, 'shi', 'go']

Unfortunately, that leaves a hole in the array. Arrays are objects, indexes ([1], [3]) are the names of the object.

array = {'0':'Peter', '1':'John'}

Names of the objects do not change after delete

Use splice for that.

	numbers.splice(2, 1);
	// numbers is ['zero', 'one', 'shi', 'go']

The second argument is the number of elements to delete.

Any additional arguments get inserted into the array at that point.

Enumeration

Since JavaScript’s arrays are really objects, the for in statement can be used to iterate over all of the properties of an array.

Unfortunately, for in makes no guarantee about the order of the properties,

Use for instead

	for (var i = 0; i < myArray.length; i += 1) {
		document.writeln(myArray[i]);
	}	

Confusion

When the property names are small sequential integers, you should use an array. Otherwise, use an object.

NOTE: typeof operator reports that the type of an array is 'object.

Use:

	var is_array = function (value) {
		return Object.prototype.toString.apply(value) === '[object Array]';
	};

##Methods JavaScript provides a set of methods for acting on arrays.

Array.prototype can be augmented as well.

Add the reduce method to arrays:

	Array.method('reduce', function (f, value) {
		var i;
		for (i = 0; i < this.length; i += 1) {
			value = f(this[i], value);
		}
		return value;
	});
	var data = [4, 8, 10];

	var add = function (a, b) {
		return a + b;
	};

	var sum = data.reduce(add, 0); // sum is 22

We can also add methods directly to an individual array:

	data.total = function ( ) {
		return this.reduce(add, 0);
	};
	total = data.total( ); // total is 22
	

Since the string 'total' is not an integer, adding a total property to an array does not change its length.

Dimensions

Add array initializers

	Array.dim = function (dimension, initial) {
		var a = [], i;
		for (i = 0; i < dimension; i += 1) {
			a[i] = initial;
		}
		return a;
	};
	// Make an array containing 10 zeros.
	var myArray = Array.dim(10, 0);

Add Matrix

	Array.matrix = function (m, n, initial) {
		var a, i, j, mat = [];
	
		for (i = 0; i < m; i += 1) {
			a = [];
			for (j = 0; j < n; j += 1) {
				a[j] = initial;
			}
			mat[i] = a;
		}
	
		return mat;
	};

	// Make a 4 * 4 matrix filled with zeros.
	var myMatrix = Array.matrix(4, 4, 0);

#8. Methods

Array

array.concat(item…)

The concat method produces a NEW array containing a shallow copy of this array with the items appended to it.

	var a = ['a', 'b', 'c'];
	var b = ['x', 'y', 'z'];
	var c = a.concat(b, true);
	// c is ['a', 'b', 'c', 'x', 'y', 'z', true]

array.join(separator)

The join method makes a string from an array.

	var a = ['a', 'b', 'c'];
	a.push('d');
	var c = a.join(''); // c is 'abcd';

array.pop( )

The pop and push methods make an array work like a stack.

	var a = ['a', 'b', 'c'];
	var c = a.pop( ); // a is ['a', 'b'] & c is 'c'

array.push(item…)

The push method appends items to the end of an array. Unlike the concat method, it modifies the array and appends array items whole. It returns the new length:

	var a = ['a', 'b', 'c'];
	var b = ['x', 'y', 'z'];
	var c = a.push(b, true);
	// a is ['a', 'b', 'c', ['x', 'y', 'z'], true]
	// c is 5;

array.reverse( )

The reverse method modifies the array by reversing the order of the elements.

It returns the array

	var a = ['a', 'b', 'c'];
	var b = a.reverse( );
	// both a and b are ['c', 'b', 'a']

array.shift( )

The shift method removes the first element from an array and returns it. Usually Slower than pop

	var a = ['a', 'b', 'c'];
	var c = a.shift( ); // a is ['b', 'c'] & c is 'a'

array.slice(start, end)

The slice method makes a shallow copy of a portion of an array.

	var a = ['a', 'b', 'c'];
	var b = a.slice(0, 1); // b is ['a']
	var c = a.slice(1); // c is ['b', 'c']
	var d = a.slice(1, 2); // d is ['b']

array.sort(comparefn)

The sort method sorts the contents of an array in place.

It sorts arrays of numbers incorrectly:

  var n = [4, 8, 15, 16, 23, 42];
  n.sort( );
  // n is [15, 16, 23, 4, 42, 8]

You may replace the comparison function with your own.

Your comparison function should take two parameters and return 0 if the two parameters are equal, a negative number if the first parameter should come first, and a positive number if the second parameter should come first.

  n.sort(function (a, b) {
  return a - b;
  });
  // n is [4, 8, 15, 16, 23, 42];

array.splice(start, deleteCount, item…)

The splice method removes elements from an array, replacing them with new items.

  var a = ['a', 'b', 'c'];
  var r = a.splice(1, 1, 'ache', 'bug');
  // a is ['a', 'ache', 'bug', 'c']
  // r is ['b']

array.unshift(item…)

The unshift method is like the push method except that it shoves the items onto the front of this array instead of at the end.

It returns the array’s new length:

  var a = ['a', 'b', 'c'];
  var r = a.unshift('?', '@');
  // a is ['?', '@', 'a', 'b', 'c']
  // r is 5

Function

function.apply(thisArg, argArray)

The apply method invokes a function, passing in the object that will be bound to this and an optional array of arguments.

The apply method is used in the The Apply Invocation Pattern

Number

number.toExponential(fractionDigits)

The toExponential method converts this number to a string in the exponential form.

The optional fractionDigits parameter controls the number of decimal places.

It should be between 0 and 20:

  document.writeln(Math.PI.toExponential(0));  // 3e+0
  document.writeln(Math.PI.toExponential(2));  // 3.14e+0
  document.writeln(Math.PI.toExponential(7));  // 3.1415927e+0
  document.writeln(Math.PI.toExponential(16)); // 3.1415926535897930e+0
  document.writeln(Math.PI.toExponential( ));  // 3.141592653589793e+0

number.toFixed(fractionDigits)

The toFixed method converts this number to a string in the decimal form.

The optional fractionDigits parameter controls the number of decimal places.

It should be between 0 and 20. The default is 0:

  document.writeln(Math.PI.toFixed(0));  // 3
  document.writeln(Math.PI.toFixed(2));  // 3.14
  document.writeln(Math.PI.toFixed(7));  // 3.1415927
  document.writeln(Math.PI.toFixed(16)); // 3.1415926535897930
  document.writeln(Math.PI.toFixed( ));  // 3

number.toPrecision(precision)

The toPrecision method converts this number to a string in the decimal form.

The optional precision parameter controls the number of digits of precision.

It should be between 1 and 21:

  document.writeln(Math.PI.toPrecision(2));  // 3.1
  document.writeln(Math.PI.toPrecision(7));  // 3.141593
  document.writeln(Math.PI.toPrecision(16)); // 3.141592653589793
  document.writeln(Math.PI.toPrecision( ));  // 3.141592653589793

number.toString(radix)

The toString method converts this number to a string.

The optional radix parameter controls radix, or base.

It should be between 2 and 36.

The default radix is base 10.

The radix parameter is most commonly used with integers, but it can be used on any number.

document.writeln(Math.PI.toString(2));  // 11.001001000011111101101010100010001000010110100011
document.writeln(Math.PI.toString(8));  // 3.1103755242102643
document.writeln(Math.PI.toString(16)); // 3.243f6a8885a3
document.writeln(Math.PI.toString( ));  // 3.141592653589793

Object

object.hasOwnProperty(name)

The hasOwnProperty method returns true if the object contains a property having the name.

The prototype chain is not examined.

This method is useless if the name is hasOwnProperty

var a = {member: true};
var b = Object.create(a); // from Chapter 3
var t = a.hasOwnProperty('member'); // t is true
var u = b.hasOwnProperty('member'); // u is false
var v = b.member; // v is true

RegExp

regexp.exec(string)

The exec method is the most powerful (and slowest) of the methods that use regular expressions.

If it successfully matches the regexp and the string, it returns an array.

The 0 element of the array will contain the substring that matched the regexp.

The 1 element is the text captured by group 1, the 2 element is the text captured by group 2, and so on.

If the match fails, it returns null.

regexp.test(string)

The test method is the simplest (and fastest) of the methods that use regular expressions.

If the regexp matches the string, it returns true; otherwise, it returns false.

Do not use the g flag with this method:

var b = /&.+;/.test('frank &amp; beans');
// b is true

String

string.charAt(pos)

The charAt method returns the character at position pos in this string.

If pos is less than zero or greater than or equal to string.length, it returns the empty string.

var name = 'Curly';
var initial = name.charAt(0); // initial is 'C'

string.charCodeAt(pos)

The charCodeAt method is the same as charAt except that instead of returning a string, it returns an integer representation of the code point value of the character at position pos in that string.

If pos is less than zero or greater than or equal to string.length, it returns NaN

var name = 'Curly';
var initial = name.charCodeAt(0); // initial is 67

string.concat(string…)

The concat method makes a new string by concatenating other strings together.

It is rarely used because the + operator is more convenient:

var s = 'C'.concat('a', 't'); // s is 'Cat'

string.indexOf(searchString, position)

The indexOf method searches for a searchString within a string.

If it is found, it returns the position of the first matched character;otherwise, it returns –1.

The optional position parameter causes the search to begin at some specified position in the string

var text = 'Mississippi';
var p = text.indexOf('ss'); // p is 2
p = text.indexOf('ss', 3); // p is 5
p = text.indexOf('ss', 6); // p is -1

string.lastIndexOf(searchString, position)

The lastIndexOf method is like the indexOf method, except that it searches from the end of the string instead of the front:

var text = 'Mississippi';
var p = text.lastIndexOf('ss'); // p is 5
p = text.lastIndexOf('ss', 3); // p is 2
p = text.lastIndexOf('ss', 6); // p is 5

string.localeCompare(that)

The localCompare method compares two strings.

The rules for how the strings are compared are not specified.

If this string is less than that string, the result is negative.

If they are equal, the result is zero.

This is similar to the convention for the array.sort comparison function:

var m = ['AAA', 'A', 'aa', 'a', 'Aa', 'aaa'];
m.sort(function (a, b) {
return a.localeCompare(b);
});
// m (in some locale) is
// ['a', 'A', 'aa', 'Aa', 'aaa', 'AAA']

string.match(regexp)

The match method matches a string and a regular expression.

How it does this depends on the g flag.

If there is no g flag, then the result of calling string.match(regexp) is the same as calling regexp.exec(string).

However, if the regexp has the g flag, then it produces an array of all the matches but excludes the capturing groups.

var text = '<html><body bgcolor=linen><p>' +
'This is <b>bold<\/b>!<\/p><\/body><\/html>';
var tags = /[^<>]+|<(\/?)([A-Za-z]+)([^<>]*)>/g;
var a, i;
a = text.match(tags);
for (i = 0; i < a.length; i += 1) {
document.writeln(('// [' + i + '] ' + a[i]).entityify( ));
}
// The result is
// [0] <html>
// [1] <body bgcolor=linen>
// [2] <p>
// [3] This is
// [4] <b>
// [5] bold
// [6] </b>
// [7] !
// [8] </p>
// [9] </body>
// [10] </html>

string.replace(searchValue,replaceValue)

The replace method does a search and replace operation on this string, producing a new string.

The searchValue argument can be a string or a regular expression object.

If it is a string, only the first occurrence of the searchValue is replaced

var result = "mother_in_law".replace('_', '-');

will produce "mother-in_law", which might be a disappointment.

If searchValue is a regular expression and if it has the g flag, then it will replace all occurrences.

If it does not have the g flag, then it will replace only the first ccurrence.

The replaceValue can be a string or a function.

Dollar sequence Replacement
$$ $
$& The matched text
$ number Capture group text
$` The text preceding the match
$' The text following the match

If the replaceValue is a function, it will be called for each match, and the string returned by the function will be used as the replacement text.

The first parameter passed to the function is the matched text.

string.search(regexp)

The search method is like the indexOf method, except that it takes a regular expression object instead of a string.

The g flag is ignored.

var text = 'and in it he says "Any damn fool could';
var pos = text.search(/["']/); // pos is 18

string.slice(start, end)

The slice method makes a new string by copying a portion of another string.

If the start parameter is negative, it adds string.length to it.

The end parameter is optional, and its default value is string.length.

If the end parameter is negative, then string.length is added to it.

The end parameter is one greater than the position of the last character.

var text = 'and in it he says "Any damn fool could';
var a = text.slice(18);
// a is '"Any damn fool could'
var b = text.slice(0, 3);
// b is 'and'
var c = text.slice(-5);
// c is 'could'
var d = text.slice(19, 32);
// d is 'Any damn fool'

string.split(separator, limit)

The split method creates an array of strings by splitting this string into pieces.

The optional limit parameter can limit the number of pieces that will be split.

The separator parameter can be a string or a regular expression.

If the separator is the empty string, an array of single characters is produced:

var digits = '0123456789';
var a = digits.split('', 5);
// a is ['0', '1', '2', '3', '456789']

Otherwise, the string is searched for all occurrences of the separator.

Each unit of text between the separators is copied into the array.

The g flag is ignored:

var ip = '192.168.1.0';
var b = ip.split('.');
// b is ['192', '168', '1', '0']
var c = '|a|b|c|'.split('|');
// c is ['', 'a', 'b', 'c', '']

string.substring(start, end)

The substring method is the same as the slice method except that it doesn’t handle the adjustment for negative parameters.

There is no reason to use the substring method. Use slice instead.

string.toLocaleLowerCase( )

The toLocaleLowerCase method produces a new string that is made by converting this string to lowercase using the rules for the locale.

This is primarily for the benefit of Turkish because in that language ‘I’ converts to ı, not ‘i’.

string.toLocaleUpperCase( )

The toLocaleUpperCase method produces a new string that is made by converting this string to uppercase using the rules for the locale.

This is primarily for the benefit of Turkish, because in that language ‘i’ converts to ‘ ’, not ‘I’.

string.toLowerCase( )

The toLowerCase method produces a new string that is made by converting this string to lowercase.

string.toUpperCase( )

The toUpperCase method produces a new string that is made by converting this string to uppercase.

String.fromCharCode(char…)

The String.fromCharCode function produces a string from a series of numbers.

var a = String.fromCharCode(67, 97, 116);
// a is 'Cat'

Awful Parts

Global Variables

A global variable is a variable that is visible in every scope.

Because a global variable can be changed by any part of the program at any time, they can significantly complicate the behavior of the program.

There are three ways to define global variables.

  1. Place a var statement outside of any function:
var foo = value;
  1. Add a property directly to the global object. ie:
window.foo = value;
  1. Use a variable without declaring it.
foo = value;

JavaScript’s policy of making forgotten variables global creates bugs that can be very difficult to find.

Scope

JavaScript uses the block syntax, but does not provide block scope:

A variable declared in a block is visible everywhere in the function containing the block.

Best practice is to declare all variables at the top of each function.

Semicolon Insertion

JavaScript has a mechanism that tries to correct faulty programs by automatically inserting semicolons.

Do not depend on this. It can mask more serious errors.

return
{
  status: true
};
// returns undefined
return {
  status: true
};
//returns an object

Reserved Words

The following words are reserved in JavaScript:

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

They cannot be used to name variables or parameters.

When reserved words are used as keys in object literals, they must be quoted.

They cannot be used with the dot notation, so it is sometimes necessary to use the bracket notation instead.

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

Unicode

JavaScript’s characters are 16 bits. That is enough to cover the original 65,536 (which is now known as the Basic Multilingual Plane).

Each of the remaining million characters can be represented as a pair of characters.

Unicode considers the pair to be a single character.

JavaScript thinks the pair is two distinct characters.

typeof

typeof null

returns object

You can fix it with:

if (my_value && typeof my_value === 'object') {
  // my_value is an object or an array!
}

Some implementations report that:

typeof /a/

is object, and others say that it is function.

parseInt

parseInt is a function that converts a string into an integer.

parseInt("16") and parseInt("16 tons") produce the same result.

If the first character of the string is 0, then the string is evaluated in base 8 instead of base 10.

parseInt("08") and parseInt("09") produce 0 as their result.

Fortunately, parseInt can take a radix parameter, so that parseInt("08",10) produces 8.

Use always the radix

+

The + operator can add or concatenate.

Which one it does depends on the types of the parameters.

If either operand is an empty string, it produces the other operand converted to a string.

If both operands are numbers, it produces the sum.

Otherwise, it converts both operands to strings and concatenates them.

Floating Point

Binary floating-point numbers are inept at handling decimal fractions, so 0.1 + 0.2 is not equal to 0.3.

Use Integer aritmetic. ie: 1.05$ = 105/100 $

NaN

The value NaN is a special quantity defined by IEEE 754. It stands for not a number, even though:

typeof NaN === 'number' // true

The value can be produced by attempting to convert a string to a number when the string is not in the form of a number. For example:

+ '0' // 0
+ 'oops' // NaN

NaN is not equal to itself.

NaN === NaN // false
NaN !== NaN // true

isNaN function that can distinguish between numbers and NaN:

isNaN(NaN) // true
isNaN(0) // false
isNaN('oops') // true
isNaN('0') // false

You may want to define your own isNumber function:

var isNumber = function isNumber(value) { 
  return typeof value === 'number' && isFinite(value);
}

Phony Arrays

Javascript arrays can be considerably worse than real arrays

The typeof operator does not distinguish between arrays and objects. You need

if (my_value && typeof my_value === 'object' && typeof my_value.length === 'number' && !(my_value.propertyIsEnumerable('length')) {
  // my_value is truly an array!
}

In any case, the test can still fail if the propertyIsEnumerable method is overridden.

Falsy Values

JavaScript has a surprisingly large set of falsy values

Value Type
0 Number
NaN (not a number) Number
'' (empty string) String
false Boolean
null Object
undefined Undefined

hasOwnProperty

Unfortunately, hasOwnProperty is a method, not an operator, so in any object it could be replaced.

Object

JavaScript’s objects are never truly empty because they can pick up members from the prototype chain.

And sometimes that matters.

Bad Parts

==

Use always === and !== instead.

'' == '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 Statement

the with statement was intended to provide a shorthand when accessing the properties of an object.

Unfortunately, its results can sometimes be unpredictable, so it should be avoided.

eval

The eval function passes a string to the JavaScript compiler and executes the result.

Should be avoided as setInterval, setTimeout and the Function constructor

continue Statement

The continue statement jumps to the top of the loop.

switch Fall Through

The switch statement was modeled after the FORTRAN IV computed go to statement.

Each case falls through into the next case unless you explicitly disrupt the flow

Block-less Statements

An if or while or do or for statement can take a block or a single statement.

if (ok)
  t = true;
//can become:
if (ok)
  t = true;
  advance( );
//which looks like:
if (ok) {
  t = true;
  advance( );
}
//but which actually means:
if (ok) {
  t = true;
}
advance( );

++ --

When ++ and -- are used , the code tended to be too tight, too tricky, too cryptic.

Don’t use them

Bitwise Operators

JavaScript has the same set of bitwise operators as Java:

& and
| or
^ xor
~ not
>> signed right shift
>>> unsigned right shift
<< left shift

Bitwise operators convert their number operands into integers, do their business, and then convert them back.

They are slow

The function Statement Versus the function Expression

The statement:

function foo( ) {}

means about the same thing as:

var foo = function foo( ) {};

function statements are subject to hoisting. This means that regardless of where a function is placed, it is moved to the top of the scope in which it is defined.

The first thing in a statement cannot be a function expression because the official grammar assumes that a statement that starts with the word function is a function statement.

The workaround is to wrap the function expression in parentheses:

(function ( ) {
  var hidden_variable;
  // This function can have some impact on
  // the environment, but introduces no new
  // global variables.
})(); 

Typed Wrappers

JavaScript has a set of typed wrappers. For example:

new Boolean(false)

Don’t use new Boolean or new Number or new String.

Also avoid new Object and new Array. Use {} and [] instead

new JavaScript’s new operator creates a new object that inherits from the operand’s prototype member, and then calls the operand, binding the new object to this. This gives the operand (which had better be a constructor function) a chance to customize the new object before it is returned to the requestor.

If youforget to use the new operator, youinstead get an ordinary function call, and this is bound to the global object instead of to a new object. That means that your function will be clobbering global variables when it attempts to initialize the new members.

Not use new at all.

void

void is an operator that takes an operand and returns undefined.

This is not useful, and it is very confusing.

Avoid void.

JSLint

Undefined Variables and Functions

JSLint expects that all variables and functions will be declared before they are used or invoked. This allows it to detect implied global variables.

Members

Since JavaScript is a loosely typed dynamic-object language, it is not possible to determine at compile time if property names are spelled correctly.

JSLint provides some assistance with this.

At the bottom of its report, JSLint displays a /*members*/ comment. It contains all of the names and string literals that were used with dot notation, subscript notation, and object literals to name the members of objects.

Options

Option Meaning
adsafe true if ADsafe.org rules should be enforced
bitwise true if bitwise operators should not be allowed
browser true if the standard browser globals should be predefined
cap true if uppercase HTML should be allowed
debug true if debugger statements should be allowed
eqeqeq true if === should be required
evil true if eval should be allowed
forin true if unfiltered for in statements should be allowed
fragment true if HTML fragments should be allowed
glovar true if var should not be allowed to declare global variables
laxbreak true if statement breaks should not be checked
nomen true if names should be checked
on true if HTML event handlers should be allowed
passfail true if the scan should stop on first error
plusplus true if ++ and -- should not be allowed
rhino true if the Rhino environment globals should be predefined
undef true if undefined global variables are errors
white true if strict whitespace rules apply
widget true if the Yahoo! Widgets globals should be predefined

Semicolon

JSLint expects that every statement be followed by ; except for for, function, if, switch, try, and while.

Line Breaking

JSLint expects long statements to be broken only after one of these punctuation characters or operators:

, . ; : { } ( [ = < > ? ! + - * / % ~ ^ | & == != <= >= += -= *= /= %= ^=

Comma

JSLint expects to see the comma used as a separator, but not as an operator

Required Blocks

JSLint expects that if and for statements will be made with blocks—that is, with statements enclosed in braces ({}).

Forbidden Blocks

JSLint expects blocks with function, if, switch, while, for, do, and try statements and nowhere else.

Expression Statements

An expression statement is expected to be an assignment, a function/method call, or delete.

for in Statement

The body of every for in statement should be wrapped in an if statement that does filtering.

switch Statement

JSLint expects that the statement before the next case or default is one of these: break, return, or throw.

var Statement

JSLint expects that:

  • Avar will be declared only once, and that it will be declared before it is used.
  • A function will be declared before it is used.
  • Parameters will not also be declared as vars.

JSLint does not expect:

  • The arguments array to be declared as a var.
  • That a variable will be declared in a block. This is because JavaScript blocks do not have block scope.

with Statement

Never use the with statement. Use a var instead.

JSLint does not expect to see a with statement.

=

JSLint does not expect to see an assignment statement in the condition part of an if or while statement. This is because it is more likely that:

  ...
}

Use

if ((a = b)) {
  ...
}

== and !=

JSLint expects === or !== operators.

Labels

JSLint expects labels only on statements that interact with break: switch, while, do, and for.

JSLint expects that labels will be distinct from variables and parameters.

Unreachable Code

JSLint expects that a return, break, continue, or throw statement will be followed by a } or case or default.

Confusing Pluses and Minuses

JSLint expects that + will not be followed by + or ++, and that - will not be followed by - or --.

++ and --

The JSLint option plusplus prohibits the use of these operators.

Bitwise Operators

JSLint does not expect bitwise operators.

eval Is Evil

JSLint does not expect evals.

void

JSLint does not expect to see void because it is confusing and not very useful.

Regular Expressions

JSLint looks for problems that may cause portability problems. It also attempts to resolve visual ambiguities by recommending explicit escapement. JSLint expects that the character preceding a regular expression literal is a ( or = or : or , character.

Constructors and new

JSLint enforces the convention that constructor functions be given names with initial uppercase letters.

JSLint does not expect to see a function invocation with an initial uppercase name unless it has the new prefix.

JSLint does not expect to see the new prefix used with functions whose names do not start with initial uppercase.

JSLint does not expect to see the wrapper forms new Number, new String, or new Boolean.

JSLint does not expect to see new Object (use {} instead).

JSLint does not expect to see new Array (use [] instead).

Not Looked For

JSLint does not chek if variables are assigned values before they are used.

JSLint does not do any kind of global analysis.

HTML

JSLint is able to handle HTML text.

JSON

JSLint can also check that JSON data structures are well formed.

Report

If JSLint is able to complete its scan, it generates a function report. It lists the following for each function:

  • The line number on which it starts.
  • Its name. In the case of anonymous functions, JSLint will “guess” the name.
  • The parameters.
  • Closure: the variables and parameters that are declared in the function that are used by its inner functions.
  • Variables: the variables declared in the function that are used only by the function.
  • Unused: the variables that are declared in the function that are not used. This may be an indication of an error.
  • Outer: variables used by this function that are declared in another function.
  • Global: global variables that are used by this function.
  • Label: statement labels that are used by this function.

The report will also include a list of all of the member names that were used.

JSON

JSON syntax

JSON has six kinds of values: objects, arrays, strings, numbers, booleans (true and false), and the special value null.

Whitespace (spaces, tabs, carriage returns, and newline characters) may be inserted before or after any value.

A JSON object is an unordered container of name/value pairs.

A name can be any string.

A value can be any JSON value, including arrays and objects.

JSON objects can be nested to any depth

The JSON array is an ordered sequence of values.

A value can be any JSON value, including arrays and objects.

alt text

alt text

alt text

A JSON string is wrapped in double quotes.

The \ character is used for escapement.

JSON allows the / character to be escaped so that JSON can be embedded in HTML <script> tags.

HTML does not allow the sequence </ except to start the </script> tag.

JSON allows <\/, which produces the same result but does not confuse HTML.

JSON numbers are like JavaScript numbers.

A leading zero is not allowed.

A number can be an integer, real, or scientific.

alt text

alt text

Using JSON Securely

Use the JSON.parse

About

JavaScript-The-Good-Parts-Summary

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published