Skip to content

Chapter 13: JavaScript in Web Browsers

This entry is a review of “Chapter 13: JavaScript in Web Browsers” from “JavaScript: The Definitive Guide”

This chapter introduces client-side JavaScript programming. It goes over the 4 different ways JavaScript can be included in a document, browser compatibility, the event-driven nature of JavaScript and briefly touches on some security issues like the Same Origin Policy and Cross-Site Scripting. It was pretty familiar territory, but a nice easy read. Below are my notes.

  • When a browser is parsing the “script” tag, if it doesn’t recognize the “type”, it ignores the contents of the script tag.
  • The script tag can have a defer and async parameter, these are a way of telling the browser that the script doesn’t contain document.write calls. deter means to defer execution until the document has been fully parsed, and async means to not block while the script is executed, but to download and execute it as soon as possible. If a script tag has both, async takes precedence.
  • Conditional Comments in IE – in addition to the HTML comments that are used, IE also has special JavaScript comments. Example:

    /*cc_on
    @if (@_jscript)
    // JS code only executed by IE
    alter("using IE");
    @end
    @*/

Chapter 12: Server-Side JavaScript

This entry is a review of “Chapter 12: Server-Side JavaScript” from “JavaScript: The Definitive Guide”

This chapter briefly introduces how to execute JavaScript in a server-side environment with Rhino and with Node.js.

Rhino

Rhino is a JavaScript engine written in Java and provided by Mozilla. It allows Java programs to execute JavaScript and JavaScript access to Java’s extensive libraries. You can have stand alone applications or just run a block of code from within a Java application. I’ve actually used Rhino at work (via Alfresco), and it’s pretty handy. I was surprised to learn that basically all Java libraries are available to the JavaScript code, though some tricky landmines exist (Java Strings aren’t the same as JavaScript String, so you have to be careful).

Node.js

Node.js has been getting a lot of buzz the past two years. I was hoping to be a little more amazed, but found it only slightly interesting. I’m not sure where I’d use it, but knowing it exists and knowing it’s basics is good. It’s takes advantage of JavaScript’s asynchronous setup and attaches to a linux environment. An example on creating a small HTTP server is given. Would I want to use this in place of PHP or Ruby on Rails? I’m not sure, and I’m not even sure if it’s aiming to be a direct backend replacement for those type of languages.

Chapter 11: JavaScript Subsets and Extensions

This entry is a review of “Chapter 11: JavaScript Subsets and Extensions” from “JavaScript: The Definitive Guide”

Some chapters just blow me away with new information, Chapter 11 was one of those chapters. It covers subsets and extensions to the JavaScript language. The subsets were created mostly for security reasons, and usually attempt to encase only the “good parts” of the language. Google Caja is a popular example of one such subset.

More interesting than the subsets were the extensions. Over the last decade Brian Eich has continually evolved the language and while many of his changes made it into EMCAScript 5.0, there are still some changes that have yet to be standardized (but will most likely get standardized in a future version of JavaScript). While the extensions shouldn’t be used for normal web development, they can be used in FireFox extensions or Rhino specific development. Below are my notes on the ones I found to be the most interesting.

  • const – Declares constants in JavaScript. Works much the same way as var. Consts can be assigned only when declared and future assignments are silently ignored. An error occurs if you try to redeclare a const.
  • let – Brings block scoping to variable declaration. Variables are hoisted to the top of their block instead of the top of their function. Let block statements also exist, which allow you to declare and execute variables for a particular block.
  • Destructuring assignments – Allows multiple variables to be assigned at once. Example:

    <script type=”application/javascript;version=1.8″>
    [a, b, [c]] = [1, 2, [3]];
    console.log(“a=”+a);
    console.log(“b=”+b);
    console.log(“c=”+c);
    let {r:red, g:green, b:blue} = {r:1, g:3, b:2};
    console.log(“red=”+red);
    console.log(“green=”+green);
    console.log(“blue=”+blue);
    </script>

    Note that since these features are non-standard, we have to speicify the JavaScript version, which makes trying them out kind of a pain.
  • for/each loop – Similar to the for-in loop, except it iterates over an object’s property values instead of an object’s property names.
  • Iterators – for-in loops have been updated in JavaScript 1.7 to work with iterable objects. These objects have an __iternator__ property that returns an object with a next() method which throws the StopIteration object when it’s done. The for-in object handles all of this behind the scenes though. There’s also a new Iterator function, which allows you to create Iterators for non-iterable objects.
  • Generators – Any function that uses the yield keyword is a generator function. When invoked, a generator function will return a generator object. A generator object represents the current execution state of its generator function. It has a next() method that resumes execution of the function and allows it to continue running until its next yield statement is encountered. A yield statement acts like a return statement (it returns a value). Return statements are allowed in a generator function, but they cannot return a value, and when encountered via the next() method, they cause the next() method to throw the StopIteration object. Generators are useful as iterators. They have a close() method (for resetting) and a send() method (for passing a value to where the last yield statement left off).
  • Array Comprehensions – Borrowed from Python. Allows a shorthand for initializing the elements of an array with the values from another array or iterable object. Example: var evensquares = [x*x for (x in range(0,10)) if (x % 2 === 0)];
  • Generator Expressions – Similar to Array Comprehensions, except wrapped in {}’s instead of []’s, and return a generator object. This allows for lazy evaluation.
  • Shorthand Functions – Allows single-statement functions to be defined without {}’s.
  • Multiple catch exceptions – Multiple catch statements can be used in conjunction with an if statement. Example:
    try {
    x = 1;
    } catch (e if e === "quit") {
    console.log("quit");
    } catch (e if e instanceof ReferenceError) {
    console.log("reference error");
    } catch (e) {
    console.log("other type of exception");
    }
  • E4X – Adds native XML support to JavaScript. I wasn’t a fan of how the resulting code looked, and luckily it looks like it’s a dying extension.

Chapter 10: Pattern Matching with Regular Expressions

This entry is a review of “Chapter 10: Pattern Matching with Regular Expressions” from “JavaScript: The Definitive Guide”

Chapter 10 is short but sweet. Regular Expressions are extremely useful and I still remember eagerly reading through regular-expressions.info when I first discovered them. This chapter is a little too short to be an introduction to the subject in general, but if you’re already familiar with them, it should get you up to speed with how they are used in JavaScript.

Notes of interest:

  • \b matches a word boundary – the position between a \w character and a \W character. Should be used as an anchor character like ^ or $.
  • \B matches a position that is not a word boundary.
  • [\b] matches a backspace.
  • (?=p) – positive look ahead (look ahead isn’t matched).
  • (?!p) – negative look ahead (look ahead isn’t matched).
  • Regular expression objects in ECMA 3 were reused instead of re-created if the same regex was created, so you have to be careful and set the lastIndex when doing matches.
  • exec and match are very similar, but match will act differently when the g flag is set.
  • Only exec and test use the lastIndex property.
  • The split function can behave a little funky if capturing groups are used.

Chapter 9: Classes and Modules

This entry is a review of “Chapter 9: Classes and Modules” from “JavaScript: The Definitive Guide”

Chapter 9 covers classes and modules in JavaScript. Classes don’t really exist in JavaScript, but you can simulate them via certain types of code patterns. The chapter is pretty long and meaty, but the subject is pretty important and essential if you’re going to be doing any serious JavaScript work. Sadly, I didn’t really pick up anything new, and found myself a little bored. That isn’t any fault of the author, I’ve just read about this subject too much before, and it sort of just felt like a review. The content was well presented though.

The chapter goes over the different ways of identifying classes (duck typing, instanceof, checking the constructor, etc etc), how to do classical inheritance (Java-like inheritance), and several example classes are presented.

Chapter 8: Functions

This entry is a review of “Chapter 8: Functions” from “JavaScript: The Definitive Guide”

Chapter 8 covers functions in JavaScript. In JavaScript, Functions are specialized Objects, though the typeof operator will for some reason return “function” for them. Most of this material has been covered in other JS books I’ve read (specially JavaScript the Good Parts and JavaScript Patterns), possibly because functions are so central to how JavaScript behaves, but there were still a few interesting bits of info.

The subject is a meaty one, and the chapter does a good job of covering difficult concepts like Closure and Functional programming. Just under 40 pages are dedicated to the topic, and most everything you’d want to know is covered. The end of the chapter focuses on Functional programming, which I’m not a fan of, but it’s still good to get some exposure to it. I’ve found myself using memoization, and have encountered partials in code bases I’ve worked with, so it’s non-essential but good to know stuff.

Below are my notes on what I found interesting in the chapter.

Function constructor

You can apparently create functions directly from the Function constructor. Since functions are objects this makes a lot of since, but it’s still a little strange. This way of creating functions should be avoided since it’s like using eval, and it’ll only create functions in the global scope, not the scope in which you create them. Example usage:

var x = new Function("x", "y", "return x + y;");

bind method

ECMAScript 5 introduces the bind method to the Function prototype. This allows you to create a new function where the inputted object is bound to the “this” parameter of the inputted function.

length property

This was one of those little things I didn’t know about that I thought was kind of neat. Every function has a length property which indicates the number of defined argument parameters.

callee and caller

Former methods of the arguments object. Both are deprecated in strict mode, due to optimization issues. callee allowed you to access the function that was currently being called (useful for anonymous functions). And caller gave you access to the call stack (the function that called the function you’re in).

Callable Objects

Other than functions, there are two other callable objects. Older versions of IE make certain build-in methods like window.alert and document.getElementById callable objects instead of functions (fixed in IE9). And RegExp objects can be invoked, which is a non-standard short-cut way of calling their exec method. This is likely to be discontinued in the future.

Chapter 7: Arrays

This entry is a review of “Chapter 7: Arrays” from “JavaScript: The Definitive Guide”

Chapter 7 covers arrays in JavaScript. In JavaScript, Arrays are specialized Objects. The chapter does a good job of covering the topic and goes over all of the different methods in the Array prototype object, including the new ones introduced in EMCAScript 5. Below are my notes on what I found interesting in the chapter.

Sparse Arrays

JavaScript allows arrays to have holes in them, and the length property of an array is simply the index of the highest element plus one. When iterating over a sparse array, undefined elements will simply return “undefined”. You can detect if an element if not present or if its value is “undefined” by using the in operator.

Detecting if an object is an array

“typeof []” will return “object”, which is no help. “x instanceof Array” will most for most values of x, but will fail when checking an array that was created in a different frame, this blog entry does a good job explaining the topic. The definitive way for checking if a variable is an array is to check its “class”. This can be done by calling the “toString” method of the Object Prototype, and binding the “this” value to the input array.

Object.prototype.toString.call(x);

ECMAScript 5 Array Methods

Many new methods are introduced to the Array prototype (listed below). These methods do not modify the array upon which they’re called, unless a function passed to them explicitly modifies the array. Typically they take in a function which is called for each element, but there are slight difference between the methods. See the linked Mozilla docs for more info.

Strings as Pseudo-Arrays

Individual characters in a String can be access using []’s (starting in IE8 and already implemented in other browsers). However, the indexing is read-only, and no Array methods are available.

Chapter 6: Objects

This entry is a review of “Chapter 6: Objects” from “JavaScript: The Definitive Guide”

Chapter 6 covers the Object data type in JavaScript. Objects are basically HashMaps in JavaScript, and while I was aware of how to use them in ECMAScript 3.0, I was not aware of the new ECMAScript 5.0 Object API. Lots of cool new utility functions have been added to the Object object. Below are my notes on what I found interesting in the chapter.

The 4 attributes of object properties

Each property you add to an object has 4 attributes – value, writable, enumerable, and configurable. Though if the property is an accessor property (getter/setter), it’s attributes become get, set, enumerable, and configurable. In ECMAScript 3.0, you couldn’t control these, and for user defined objects they (writable, enumerable, and configurable) were always true. In 5.0 you can change them.

  • value – The value of the property.
  • writable – Whether or not you can set the property.
  • configurable – Whether or not the object attributes (other than writable) can be configured/changed. Also controls if the property can be deleted.
  • enumerable – Whether or not the property shows up when they are enumerated in a for-in loop.
  • get – A function which sets a property (for accessor properties only).
  • set – A function which sets a property (for accessor properties only).

Getter and Setter / Accessor Properties

Defined like so:

var o = {
x: 1,
y: 2,
get z() {return this.x + this.y;},
set z(newValue) {this.x = newValue/2; this.y=newValue/2;}
};
console.log(o.z);
o.z = 10;
console.log(o.x + "," + o.y + "," + o.z);

Object attributes

Objects have 3 attributes – prototype, class, and extendable.

  • prototype – __proto__ in FireFox, though there is no cross-browser way to access the prototype of an object. In ECMAScript 5.0, objects have a isPrototypeOf method (ex: o.isPrototypeOf(x)) which will let you check for prototypes. Also, with the new Object.create method you can control the prototype of an object.
  • class – There is no way to set this attribute, and only an indirect way to query for it (ex: Object.prototype.toString.call(o) -> “[object class]”). User defined objects will have a class of “Object” and there is no way to change this.
  • extendable – Specifies if a new property can be added to an object. You can query for this attribute with Object.isExtendable(o), and set it with Object.preventExtensions(o) (though there is no way to make it extendable once you’ve prevented extensions).

New Object utility functions

  • MyObject.isPrototypeOf(o) – Allows you to check to see if MyObject is the prototype of o.
  • MyObject.propertyIsEnumerable(x) – Tells if you property x of MyObject is enumerable.
  • MyObject.toJSON – Controls how an object is transformed into JSON via the JSON.stringify method.
  • MyObject.toLocaleString – For creating a localized string representation of an object. Certain objects like Date and Array have custom versions.

Specific to the Object object:

  • Object.create – New way of creating an object. Takes in an optional first parameter which specifies a prototype, and an optional second parameter which specifies a descriptor object (for setting properties and their attributes).
  • Object.getOwnPropertyDescriptor(obj, prop) – Returns the descriptor for the propery prop of object obj.
  • Object.definePropert[y|ies](obj, prop_des) – Allows you to define a property and its attributes. If a new property is being added, default values are given for the missing attributes, if a property is being redefined, unpassed-in attributes will remain the same.
  • Object.keys(o) – Returns an array of all own enumerable properties of object o.
  • Object.getOwnPropertyNames(o) – Returns an array of all own properties of object o.
  • Object.seal(o) – Prevents new properties from being added to o and all existing properties are changed to non-configurable.
  • Object.freeze(o) – Properties can’t be added or removed from o, and none of its property’s attributes can be changed.
  • Object.preventExtensions(o) – No new properties will be able to be added to o.
  • Object.isFrozen(o) – Tells you if o is frozen or not.
  • Object.isSealed(o) – Tells you if o is sealed or not.
  • Object.isExtendable(o) – Tells you if o is extendable or not.

I do wonder if I’ll ever use most of these functions, but they’re definitely good to know about. Anyway, great chapter full of lots of interesting information.

Chapter 5: Statements

This entry is a review of “Chapter 5: Statements” from “JavaScript: The Definitive Guide”

Chapter 5 covers JavaScript statements. If expressions are phrases, statements are sentences. The chapter did a good job of covering the different types of statements – simple expressions, compound (inside of {}’s), declarative (var, function), conditional, loops, jump, and miscellaneous (with, debugger).

“use strict”

This is actually a “directive”, but directives are very close to statements so Flanagan lumped them in here. “use strict” is really cool because it quietly does nothing in browsers that don’t support it. For those browsers that do support it, the JavaScript engine enables strict mode, which aims to eliminate a number of JavaScript’s deficiencies. Chief among these is JavaScript’s rule of creating global variables when a variable is set that hasn’t been declared (in strict mode, you get an error if you try to use an undeclared variable).

Other improvements are that the with statement is gone, functions’ arguments object is static and doesn’t change when inputs are changed, eval has its own private variable space, you get errors thrown in situations where they’d used to just silently fail, and a whole host of small clean-up fixes.

debugger statement

I never knew this existed. Basically it acts a breakpoint in your code. If a debugger is available, your browser will attempt to launch it, but it doesn’t have to (MDN docs here). If you’re curious how it’s used, here’s an interesting tutorial which showed how it was used back in the day. My guess is this keyword is no longer used now that most browsers have pretty high tech debugging utilities.

try/catch/finally statement

How to use this is pretty obvious, interesting things to note though are that the exception variable in the catch block is block scoped and not function scoped, and the finally block will toss out any exceptions that were thrown if it uses a jump statement (break, continue, throw, return). A return statement in the finally block will also trump a return statement in the try or catch blocks.

Looping Tricks

I thought the following loop which gets a list of object properties was pretty clever:

for (a[ii++] in o) ; // copies all of the enumerable properties from o into the a array

Chapter 4: Expressions and Operators

This entry is a review of “Chapter 4: Expressions and Operators” from “JavaScript: The Definitive Guide”

Chapter 4 covers JavaScript expressions and operators. It goes over what an expression is, what an operator is, what the operator precedence is, and discusses what each operator is what its effects and side effects are. It’s provides a thorough look at the topic and was pretty easy reading. Not a whole lot of new ground here for me, but there were a few new interesting bits I picked up.

eval Function

Easily the most interesting section of the chapter. The author comments that eval is a built in function, though it probably should have been implemented as an operator. Since existing code relies on it as a function, we’re mostly stuck with it as one, though as EMCAScript as progressed, it’s migrated closer and closer to acting like an operator.

Besides security concerns, eval also hinders the browser’s JavaScript optimization abilities. This is because the optimizer can’t optimize what’s passed into eval and because eval can modify and add new functions and variables to the environment it’s called in (it takes the scope of where it’s called). In EMCAScript 5.0 strict mode, eval’s code has its own private environment and can’t create new variables or functions in the scope it’s called in (though it can still modify local and global objects), and it can’t be overwritten like a normal function.

When an aliased version of eval is called (e.g., x = eval; x(“alert(‘y = ‘+y)”);), it’s executed in the global scope and not the local scope.

delete Operator

For removing properties from an object. Can’t delete variables/properties created with var and the function declaration statement (also can’t delete function declaration parameters). If used on an array, it doesn’t change the array’s length, it basically just puts a hole in the array.

Bitwise Operators

Under the covers, Numbers in JavaScript are represented as 64-bit floating point numbers. When bitwise operators are used, Numbers are coerced into a 32 integer representation and the operations and preformed as if the numbers were 32 bit integers.

void Operator

Takes in an operand and returns the mysterious “undefined” valued. I’ve read about this before, but I’ve yet to ever use it. It’s good if you need to execute an expression but need its return value to be “undefined”.

Comma Operator

Processes it’s operators from left to right, and returns the value of its last operand. One of those obvious operators we use everyday but never think about.