Discover millions of ebooks, audiobooks, and so much more with a free trial

Only $11.99/month after trial. Cancel anytime.

Professional JavaScript for Web Developers
Professional JavaScript for Web Developers
Professional JavaScript for Web Developers
Ebook2,088 pages25 hours

Professional JavaScript for Web Developers

Rating: 0 out of 5 stars

()

Read preview

About this ebook

Update your skill set for ES 6 and 7 with the ultimate JavaScript guide for pros

Professional JavaScript for Web Developers is the essential guide to next-level JavaScript development. Written for intermediate-to-advanced programmers, this book jumps right into the technical details to help you clean up your code and become a more sophisticated JavaScript developer. From JavaScript-specific object-oriented programming and inheritance, to combining JavaScript with HTML and other markup languages, expert instruction walks you through the fundamentals and beyond. This new fourth edition has been updated to cover ECMAScript 6 and 7 (also known as ES2015 and ES2016) and the major re-imagination and departure from ES 5.1; new frameworks and libraries, new techniques, new testing tools, and more are explained in detail for the professional developer, with a practical focus that helps you put your new skills to work on real-world projects.

The latest—and most dramatic—ES release is already being incorporated into JavaScript engines in major browsers; this, coupled with the rise in mobile web traffic increasing demand for responsive, dynamic web design, means that all web developers need to update their skills—and this book is your ideal resource for quick, relevant guidance.

  • Get up to date with ECMAScript 6 and 7, new frameworks, and new libraries
  • Delve into web animation, emerging APIs, and build systems
  • Test more effectively with mocks, unit tests, functional tests, and other tools
  • Plan your builds for future ES releases

Even if you think you know JavaScript, new ES releases bring big changes that will affect the way you work. For a professional-level update that doesn't waste time on coding fundamentals, Professional JavaScript for Web Developers is the ultimate resource to bring you up to speed.

LanguageEnglish
PublisherWiley
Release dateOct 2, 2019
ISBN9781119366577
Professional JavaScript for Web Developers

Read more from Matt Frisbie

Related to Professional JavaScript for Web Developers

Related ebooks

Programming For You

View More

Related articles

Reviews for Professional JavaScript for Web Developers

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    Book preview

    Professional JavaScript for Web Developers - Matt Frisbie

    INTRODUCTION

    A tech lead at Google once shared with me a compelling perspective on JavaScript: It's not really a cohesive programming language—at least not in the formal sense. The ECMA-262 specification defines JavaScript, but there is no single true implementation of it. What's more, the language is far from hermetic. It swims in a veritable ocean of adjacent specifications that govern APIs for everything that JavaScript touches: the DOM, network requests, system hardware, storage, events, files, cryptography, and hundreds of others. Web browsers and their various JavaScript engines all implement these specifications as they see fit. Chrome has Blink/V8, Firefox has Gecko/SpiderMoney, and Safari has WebKit/JavaScriptCore. Browsers will run nearly all JavaScript in a way that conforms to the specifications, but the web is littered with examples of each browser's idiosyncrasies. Therefore, JavaScript is more accurately characterized as a constellation of browser implementations.

    Although web purists might insist that JavaScript should not be an integral component of web pages, they must concede that the modern web is severely diminished without it. It is not hyperbolic to say that JavaScript is virtually inescapable: Phones, computers, tablets, televisions, game consoles, smart watches, refrigerators, and even cars now feature web browsers that run JavaScript. Nearly three billion people now use a smartphone that includes a web browser. The language's vibrant community churns out a deluge of high-quality open source projects. Browsers now feature first-class support for APIs that emulate native mobile apps. In Stack Overflow's 2019 Developer Survey, JavaScript was voted the most popular programming language for the seventh consecutive year.

    The JavaScript renaissance is upon us.

    In this book, JavaScript is covered from its very beginning in the earliest Netscape browsers to the present-day incarnations flush with support for a dizzying spectrum of browser technologies. The book covers a large number of advanced topics in meticulous detail, yet it ensures the reader understands how to use these topics and where they are appropriate. In short, you learn how to apply JavaScript solutions to business problems faced by web developers everywhere.

    WHO THIS BOOK IS FOR

    This book is aimed at three groups of readers:

    Experienced developers familiar with object-oriented programming who are looking to learn JavaScript as it relates to traditional OO languages such as Java and C++

    Web application developers attempting to enhance the usability of their web sites and web applications

    Novice JavaScript developers aiming to better understand the language

    In addition, familiarity with the following related technologies is a strong indicator that this book is for you:

    Java

    PHP

    Python

    Ruby

    Golang

    HTML

    CSS

    This book is not aimed at beginners lacking a basic computer science background or those looking to add some simple user interactions to websites. These readers should instead refer to Wrox's Beginning JavaScript, 5th Edition (Wiley, 2015).

    WHAT THIS BOOK COVERS

    Professional JavaScript for Web Developers, 4th Edition, provides a developer-level introduction, along with the more advanced and useful features of JavaScript.

    The book begins with an exploration of how JavaScript originated and evolved into what it is today. A detailed discussion of the components that make up a JavaScript implementation follows, with specific focus on standards such as ECMAScript and the Document Object Model (DOM).

    Building on that base, the book moves on to cover basic concepts of JavaScript, including classes, promises, iterators, and proxies. This is followed by an in-depth examination of client detection, events, animations, forms, errors, and JSON.

    The last part of the book is focused on the newest and most important specifications that have emerged in the past few years. This includes fetch, modules, web workers, service workers, and a collection of emerging APIs.

    HOW THIS BOOK IS STRUCTURED

    This book comprises the following chapters:

    What Is JavaScript?—Explains the origins of JavaScript: where it came from, how it evolved, and what it is today. Concepts introduced include the relationship between JavaScript and ECMAScript, the Document Object Model (DOM), and the Browser Object Model (BOM). A discussion of the relevant standards from the European Computer Manufacturer's Association (ECMA) and the World Wide Web Consortium (W3C) is also included.

    JavaScript in HTML—Examines how JavaScript is used in conjunction with HTML to create dynamic web pages. Introduces the various ways of embedding JavaScript into a page and includes a discussion surrounding the JavaScript content-type and its relationship to the

    Language Basics—Introduces basic language concepts, including syntax and flow control statements. Explains the syntactic similarities of JavaScript and other C-based languages and points out the differences. Type coercion is introduced as it relates to built-in operators. Covers all language primitives, including the Symbol type.

    Variables, Scope, and Memory—Explores how variables are handled in JavaScript given their loosely typed nature. A discussion of the differences between primitive and reference values is included, as is information about execution context as it relates to variables. Also, a discussion about garbage collection in JavaScript covers how memory is reclaimed when variables go out of scope.

    Basic Reference Types—Covers all of the details regarding JavaScript's built-in reference types, such as Date, Regexp, primitives, and primitive wrappers. Each reference type is discussed both in theory and in how they relate to browser implementations.

    Collection Reference Types—Continues the book's coverage of built-in reference types with Object, Array, Map, WeakMap, Set, and WeakSet.

    Iterators and Generators—Introduces two new fundamental concepts in recent versions of ECMAScript: iterators and generators. Each is discussed both in terms of its most fundamental behavior as well as how it is used in relation to existing language constructs.

    Objects, Classes, and Object-Oriented Programming—Explains how to use classes and object-oriented programming in JavaScript. Begins with an in-depth discussion of the JavaScript Object type and continues into coverage of prototypal inheritance. Following this is a complete discussion of ES6 classes and how they are a close sibling of prototypal inheritance.

    Proxies and Reflect—Introduces two closely related concepts: Proxy and the Reflect API. These can be used to intercept and shim additional behavior into fundamental operations within the language.

    Functions—Explores one of the most powerful aspects of JavaScript: function expressions. Topics include closures, the this object, the module pattern, the creation of private object members, arrow functions, default parameters, and spread operators.

    Promises and Async Programming—Introduces two new closely related asynchronous programming constructs: the Promise type and async/await. The chapter begins with a discussion of the asynchronous JavaScript paradigm and continues into coverage of how promises are used and their relationship to async functions.

    The Browser Object Model—Introduces the Browser Object Model (BOM), which is responsible for objects allowing interaction with the browser itself. Each of the BOM objects is covered, including window, document, location, navigator, and screen.

    Client Detection—Explains various approaches to detecting the client machine and its capabilities. Different techniques include capability detection and user-agent string detection. The chapter covers the pros and cons of each approach, as well as situational appropriateness.

    The Document Object Model—Introduces the Document Object Model (DOM) objects available in JavaScript as defined in DOM Level 1. A brief introduction to XML and its relationship to the DOM gives way to an in-depth exploration of the entire DOM and how it allows developers to manipulate a page.

    DOM Extensions—Explains how other APIs, as well as the browsers themselves, extend the DOM with more functionality. Topics include the Selectors API, the Element Traversal API, and HTML5 extensions.

    DOM Levels 2 and 3—Builds on the previous two chapters, explaining how DOM Levels 2 and 3 augmented the DOM with additional properties, methods, and objects. Includes coverage of DOM4 additions, such as mutation observers.

    Events—Explains the nature of events in JavaScript, where they originated, and how the DOM redefined how events should work.

    Animation and Graphics with Canvas—Discusses the tag and how to use it to create on-the-fly graphics. Both the 2D context and the WebGL (3D) context are covered, providing you with a good starting point for creating animations and games. Includes coverage of both WebGL1 and WebGL2.

    Scripting Forms—Explores using JavaScript to enhance form interactions and work around browser limitations. Discussion focuses on individual form elements such as text boxes and select boxes and on data validation and manipulation.

    JavaScript APIs—Covers an assortment of JavaScript APIs, including Atomics, Encoding, File, Blob, Notifications, Streams, Timing, Web Components, and Web Cryptography.

    Error Handling and Debugging—Discusses how browsers handle errors in JavaScript code and presents several ways to handle errors. Debugging tools and techniques are also discussed for each browser, including recommendations for simplifying the debugging process.

    XML in JavaScript—Presents the features of JavaScript used to read and manipulate eXtensible Markup Language (XML) data. Explains the differences in support and objects in various web browsers and offers suggestions for easier cross-browser coding. This chapter also covers the use of eXtensible Stylesheet Language Transformations (XSLT) to transform XML data on the client.

    JSON—Introduces the JSON data format as an alternative to XML. Discusses browser-native JSON parsing and serialization as well as security considerations when using JSON.

    Network Requests and Remote Resources—Explores all of the most common ways that data and assets are requested by the browser. Includes coverage of the legacy XMLHttpRequest as well as the modern Fetch API.

    Client-Side Storage—Discusses how to detect when an application is offline and provides various techniques for storing data on the client machine. Begins with a discussion of the most commonly supported feature, cookies, and then discusses newer functionality such as Web Storage and IndexedDB.

    Modules—Discusses the module pattern and its implications on codebases. Following this, the chapter covers pre-ES6 module loaders such as CommonJS, AMD, and UMD. Ends with detailed coverage on the new ES6 module pattern and how to use it properly.

    Workers—Covers dedicated workers, shared workers, and service workers in-depth. Includes a discussion of how workers behave both at the operating system and browser level, as well as strategies for how best to use the various types of workers.

    Best Practices—Explores approaches to working with JavaScript in an enterprise environment. Techniques for better maintainability are discussed, including coding techniques, formatting, and general programming practices. The chapter also covers execution performance and introduces several techniques for speed optimization. Last, the chapter covers deployment issues, including how to create a build process.

    WHAT YOU NEED TO USE THIS BOOK

    To run the samples in the book, you need the following:

    Any modern operating system, such as Windows, Linux, Mac OS, Android, or iOS

    Any modern browser, such as IE11+, Edge 12+, Firefox 26+, Chrome 39+, Safari 10+, Opera 26+, or iOS Safari 10+

    The complete source code is available for download from https://www.wiley.com/en-us/Professional+JavaScript+for+Web+Developers%2C+4th+Edition-p-9781119366447.

    1

    What Is JavaScript?

    WHAT'S IN THIS CHAPTER?

    Review of JavaScript history

    What JavaScript is

    How JavaScript and ECMAScript are related

    The different versions of JavaScript

    WROX.COM DOWNLOADS FOR THIS CHAPTER

    Please note that all the code examples for this chapter are available as a part of this chapter's code download on the book's website at www.wrox.com/go/projavascript4e on the Download Code tab.

    When JavaScript first appeared in 1995, its main purpose was to handle some of the input validation that had previously been left to server-side languages such as Perl. Prior to that time, a round-trip to the server was needed to determine if a required field had been left blank or an entered value was invalid. Netscape Navigator sought to change that with the introduction of JavaScript. The capability to handle some basic validation on the client was an exciting new feature at a time when use of telephone modems was widespread. The associated slow speeds turned every trip to the server into an exercise in patience.

    Since that time, JavaScript has grown into an important feature of every major web browser on the market. No longer bound to simple data validation, JavaScript now interacts with nearly all aspects of the browser window and its contents. JavaScript is recognized as a full programming language, capable of complex calculations and interactions, including closures, anonymous (lambda) functions, and even metaprogramming. JavaScript has become such an important part of the web that even alternative browsers, including those on mobile phones and those designed for users with disabilities, support it. Even Microsoft, with its own client-side scripting language called VBScript, ended up including its own JavaScript implementation in Internet Explorer from its earliest version.

    The rise of JavaScript from a simple input validator to a powerful programming language could not have been predicted. JavaScript is at once a very simple and very complicated language that takes minutes to learn but years to master. To begin down the path to using JavaScript's full potential, it is important to understand its nature, history, and limitations.

    A SHORT HISTORY

    As the web gained popularity, a gradual demand for client-side scripting languages developed. At the time, most Internet users were connecting over a 28.8 kbps modem even though web pages were growing in size and complexity. Adding to users' pain was the large number of round-trips to the server required for simple form validation. Imagine filling out a form, clicking the Submit button, waiting 30 seconds for processing, and then being met with a message indicating that you forgot to complete a required field. Netscape, at that time on the cutting edge of technological innovation, began seriously considering the development of a client-side scripting language to handle simple processing.

    In 1995, a Netscape developer named Brendan Eich began developing a scripting language called Mocha (later renamed as LiveScript) for the release of Netscape Navigator 2. The intention was to use it both in the browser and on the server, where it was to be called LiveWire.

    Netscape entered into a development alliance with Sun Microsystems to complete the implementation of LiveScript in time for release. Just before Netscape Navigator 2 was officially released, Netscape changed LiveScript's name to JavaScript to capitalize on the buzz that Java was receiving from the press.

    Because JavaScript 1.0 was such a hit, Netscape released version 1.1 in Netscape Navigator 3. The popularity of the fledgling web was reaching new heights, and Netscape had positioned itself to be the leading company in the market. At this time, Microsoft decided to put more resources into a competing browser named Internet Explorer. Shortly after Netscape Navigator 3 was released, Microsoft introduced Internet Explorer 3 with a JavaScript implementation called JScript (so called to avoid any possible licensing issues with Netscape). This major step for Microsoft into the realm of web browsers in August 1996 is now a date that lives in infamy for Netscape, but it also represented a major step forward in the development of JavaScript as a language.

    Microsoft's implementation of JavaScript meant that there were two different JavaScript versions floating around: JavaScript in Netscape Navigator and JScript in Internet Explorer. Unlike C and many other programming languages, JavaScript had no standards governing its syntax or features, and the three different versions only highlighted this problem. With industry fears mounting, it was decided that the language must be standardized.

    In 1997, JavaScript 1.1 was submitted to the European Computer Manufacturers Association (Ecma) as a proposal. Technical Committee #39 (TC39) was assigned to standardize the syntax and semantics of a general purpose, cross-platform, vendor-neutral scripting language (www.ecma-international.org/memento/TC39.htm). Made up of programmers from Netscape, Sun, Microsoft, Borland, NOMBAS, and other companies with interest in the future of scripting, TC39 met for months to hammer out ECMA-262, a standard defining a new scripting language named ECMAScript (often pronounced as ek-ma-script).

    The following year, the International Organization for Standardization and International Electrotechnical Commission (ISO/IEC) also adopted ECMAScript as a standard (ISO/IEC-16262). Since that time, browsers have tried, with varying degrees of success, to use ECMAScript as a basis for their JavaScript implementations.

    JAVASCRIPT IMPLEMENTATIONS

    Though JavaScript and ECMAScript are often used synonymously, JavaScript is much more than just what is defined in ECMA-262. Indeed, a complete JavaScript implementation is made up of the following three distinct parts (see Figure 1-1):

    Illustration of the ECMAS script depicting the first edition of JavaScript.

    FIGURE 1-1

    The Core (ECMAScript)

    The Document Object Model (DOM)

    The Browser Object Model (BOM)

    ECMAScript

    ECMAScript, the language defined in ECMA-262, isn't tied to web browsers. In fact, the language has no methods for input or output whatsoever. ECMA-262 defines this language as a base upon which more-robust scripting languages may be built. Web browsers are just one host environment in which an ECMAScript implementation may exist. A host environment provides the base implementation of ECMAScript and implementation extensions designed to interface with the environment itself. Extensions, such as the Document Object Model (DOM), use ECMAScript's core types and syntax to provide additional functionality that's more specific to the environment. Other host environments include NodeJS, a server-side JavaScript platform, and the increasingly obsolete Adobe Flash.

    What exactly does ECMA-262 specify if it doesn't reference web browsers? On a very basic level, it describes the following parts of the language:

    Syntax

    Types

    Statements

    Keywords

    Reserved words

    Operators

    Global objects

    ECMAScript is simply a description of a language implementing all of the facets described in the specification. JavaScript implements ECMAScript, but so does Adobe ActionScript.

    ECMAScript Editions

    The different versions of ECMAScript are defined as editions (referring to the edition of ECMA-262 in which that particular implementation is described). The most recent edition of ECMA-262 is edition 7, released in 2016. The first edition of ECMA-262 was essentially the same as Netscape's JavaScript 1.1 but with all references to browser-specific code removed and a few minor changes: ECMA-262 required support for the Unicode standard (to support multiple languages) and that objects be platform-independent (Netscape JavaScript 1.1 actually had different implementations of objects, such as the Date object, depending on the platform). This was a major reason why JavaScript 1.1 and 1.2 did not conform to the first edition of ECMA-262.

    The second edition of ECMA-262 was largely editorial. The standard was updated to get into strict agreement with ISO/IEC-16262 and didn't feature any additions, changes, or omissions. ECMAScript implementations typically don't use the second edition as a measure of conformance.

    The third edition of ECMA-262 was the first real update to the standard. It provided updates to string handling, the definition of errors, and numeric outputs. It also added support for regular expressions, new control statements, try-catch exception handling, and small changes to better prepare the standard for internationalization. To many, this marked the arrival of ECMAScript as a true programming language.

    The fourth edition of ECMA-262 was a complete overhaul of the language. In response to the popularity of JavaScript on the web, developers began revising ECMAScript to meet the growing demands of web development around the world. In response, Ecma TC39 reconvened to decide the future of the language. The resulting specification defined an almost completely new language based on the third edition. The fourth edition includes strongly typed variables, new statements and data structures, true classes and classical inheritance, and new ways to interact with data.

    As an alternate proposal, a specification called ECMAScript 3.1, was developed as a smaller evolution of the language by a subcommittee of TC39, who believed that the fourth edition was too big of a jump for the language. The result was a smaller proposal with incremental changes to ECMAScript that could be implemented on top of existing JavaScript engines. Ultimately, the ES3.1 subcommittee won over support from TC39, and the fourth edition of ECMA-262 was abandoned before officially being published.

    ECMAScript 3.1 became ECMA-262, fifth edition, and was officially published on December 3, 2009. The fifth edition sought to clarify perceived ambiguities of the third edition and introduce additional functionality. The new functionality includes a native JSON object for parsing and serializing JSON data, methods for inheritance and advanced property definition, and the inclusion of a new strict mode that slightly augments how ECMAScript engines interpret and execute code. The fifth edition saw a maintenance revision in June 2011; this was merely for corrections in the specification and introduced no new language or library features.

    The sixth edition of ECMA-262—colloquially referred to as ES6, ES2015, or ES Harmony—was published in June 2015, and contains arguably the most important collection of enhancements to the specification since its inception. ES6 adds formal support for classes, modules, iterators, generators, arrow functions, promises, reflection, proxies, and a host of new data types.

    The seventh edition of ECMA-262, dubbed ES7 or ES2016, was published in June of 2016. This revision included only a handful of syntactical additions such as Array.prototype.includes and the exponentiation operator.

    The eighth edition of ECMA-262, called ES8 or ES2017, was finalized in January of 2017. This revision included asynchronous iteration, rest and spread properties, a collection of new regular expression features, a Promise finally() catchall handler, and template literal revisions.

    The ninth edition of ECMA-262 is still being finalized, but it already has a large number of features in stage 3. Its most significant addition will likely be dynamic importing of ES6 modules.

    What Does ECMAScript Conformance Mean?

    ECMA-262 lays out the definition of ECMAScript conformance. To be considered an implementation of ECMAScript, an implementation must do the following:

    Support all types, values, objects, properties, functions, and program syntax and semantics as they are described in ECMA-262.

    Support the Unicode character standard.

    Additionally, a conforming implementation may do the following:

    Add additional types, values, objects, properties, and functions that are not specified in ECMA-262. ECMA-262 describes these additions as primarily new objects or new properties of objects not given in the specification.

    Support program and regular expression syntax that is not defined in ECMA-262 (meaning that the built-in regular-expression support is allowed to be altered and extended).

    These criteria give implementation developers a great amount of power and flexibility for developing new languages based on ECMAScript, which partly accounts for its popularity.

    ECMAScript Support in Web Browsers

    Netscape Navigator 3 shipped with JavaScript 1.1 in 1996. That same JavaScript 1.1 specification was then submitted to Ecma as a proposal for the new standard, ECMA-262. With JavaScript's explosive popularity, Netscape was very happy to start developing version 1.2. There was, however, one problem: Ecma hadn't yet accepted Netscape's proposal.

    Shortly after Netscape Navigator 3 was released, Microsoft introduced Internet Explorer 3. This version of IE shipped with JScript 1.0, which was supposed to be equivalent to JavaScript 1.1. However, because of undocumented and improperly replicated features, JScript 1.0 fell far short of JavaScript 1.1.

    Netscape Navigator 4 was shipped in 1997 with JavaScript 1.2 before the first edition of ECMA-262 was accepted and standardized later that year. As a result, JavaScript 1.2 is not compliant with the first edition of ECMAScript even though ECMAScript was supposed to be based on JavaScript 1.1.

    The next update to JScript occurred in Internet Explorer 4 with JScript version 3.0 (version 2.0 was released in Microsoft Internet Information Server version 3.0 but was never included in a browser). Microsoft put out a press release touting JScript 3.0 as the first truly Ecma-compliant scripting language in the world. At that time, ECMA-262 hadn't yet been finalized, so JScript 3.0 suffered the same fate as JavaScript 1.2: it did not comply with the final ECMAScript standard.

    Netscape opted to update its JavaScript implementation in Netscape Navigator 4.06 to JavaScript 1.3, which brought Netscape into full compliance with the first edition of ECMA-262. Netscape added support for the Unicode standard and made all objects platform-independent while keeping the features that were introduced in JavaScript 1.2.

    When Netscape released its source code to the public as the Mozilla project, it was anticipated that JavaScript 1.4 would be shipped with Netscape Navigator 5. However, a radical decision to completely redesign the Netscape code from the bottom up derailed that effort. JavaScript 1.4 was released only as a server-side language for Netscape Enterprise Server and never made it into a web browser.

    By 2008, the five major web browsers (Internet Explorer, Firefox, Safari, Chrome, and Opera) all complied with the third edition of ECMA-262. Internet Explorer 8 was the first to start implementing the fifth edition of ECMA-262 specification and delivered complete support in Internet Explorer 9. Firefox 4 soon followed suit. The following table lists ECMAScript support in the most popular web browsers.

    *Incomplete implementations

    The Document Object Model

    The Document Object Model (DOM) is an application programming interface (API) for XML that was extended for use in HTML. The DOM maps out an entire page as a hierarchy of nodes. Each part of an HTML or XML page is a type of node containing different kinds of data. Consider the following HTML page:

          Sample Page        

    Hello World!

     

    This code can be diagrammed into a hierarchy of nodes using the DOM (see Figure 1-2).

    Illustration of the DOM (Document Objective Model) where developers are allowed unprecedented level of control over content and structure.

    FIGURE 1-2

    By creating a tree to represent a document, the DOM allows developers an unprecedented level of control over its content and structure. Nodes can be removed, added, replaced, and modified easily by using the DOM API.

    Why the DOM Is Necessary

    With Internet Explorer 4 and Netscape Navigator 4 each supporting different forms of Dynamic HTML (DHTML), developers for the first time could alter the appearance and content of a web page without reloading it. This represented a tremendous step forward in web technology but also a huge problem. Netscape and Microsoft went separate ways in developing DHTML, thus ending the period when developers could write a single HTML page that could be accessed by any web browser.

    It was decided that something had to be done to preserve the cross-platform nature of the web. The fear was that if someone didn't rein in Netscape and Microsoft, the web would develop into two distinct factions that were exclusive to targeted browsers. It was then that the World Wide Web Consortium (W3C), the body charged with creating standards for web communication, began working on the DOM.

    DOM Levels

    DOM Level 1 became a W3C recommendation in October 1998. It consisted of two modules: the DOM Core, which provided a way to map the structure of an XML-based document to allow for easy access to and manipulation of any part of a document, and the DOM HTML, which extended the DOM Core by adding HTML-specific objects and methods.

    NOTE Note that the DOM is not JavaScript-specific and indeed has been implemented in numerous other languages. For web browsers, however, the DOM has been implemented using ECMAScript and now makes up a large part of the JavaScript language.

    Whereas the goal of DOM Level 1 was to map out the structure of a document, the aims of DOM Level 2 were much broader. This extension of the original DOM added support for mouse and user-interface events (long supported by DHTML), ranges, and traversals (methods to iterate over a DOM document), and support for Cascading Style Sheets (CSS) through object interfaces. The original DOM Core introduced in Level 1 was also extended to include support for XML namespaces.

    DOM Level 2 introduced the following new modules of the DOM to deal with new types of interfaces:

    DOM views—Describes interfaces to keep track of the various views of a document (the document before and after CSS styling, for example)

    DOM events—Describes interfaces for events and event handling

    DOM style—Describes interfaces to deal with CSS-based styling of elements

    DOM traversal and range—Describes interfaces to traverse and manipulate a document tree

    DOM Level 3 further extends the DOM with the introduction of methods to load and save documents in a uniform way (contained in a new module called DOM Load and Save) and methods to validate a document (DOM Validation). In Level 3, the DOM Core is extended to support all of XML 1.0, including XML Infoset, XPath, and XML Base.

    Presently, the W3C no longer maintains the DOM as a set of levels, but rather as the DOM Living Standard, snapshots of which are termed DOM4. Among its introductions is the addition of Mutation Observers to replace Mutation Events.

    NOTE When reading about the DOM, you may come across references to DOM Level 0. Note that there is no standard called DOM Level 0; it is simply a reference point in the history of the DOM. DOM Level 0 is considered to be the original DHTML supported in Internet Explorer 4.0 and Netscape Navigator 4.0.

    Other DOMs

    Aside from the DOM Core and DOM HTML interfaces, several other languages have had their own DOM standards published. The languages in the following list are XML-based, and each DOM adds methods and interfaces unique to a particular language:

    Scalable Vector Graphics (SVG) 1.0

    Mathematical Markup Language (MathML) 1.0

    Synchronized Multimedia Integration Language (SMIL)

    Additionally, other languages have developed their own DOM implementations, such as Mozilla's XML User Interface Language (XUL). However, only the languages in the preceding list are standard recommendations from W3C.

    DOM Support in Web Browsers

    The DOM had been a standard for some time before web browsers started implementing it. Internet Explorer made its first attempt with version 5, but it didn't have any realistic DOM support until version 5.5, when it implemented most of DOM Level 1. Internet Explorer didn't introduce new DOM functionality in versions 6 and 7, though version 8 introduced some bug fixes.

    For Netscape, no DOM support existed until Netscape 6 (Mozilla 0.6.0) was introduced. After Netscape 7, Mozilla switched its development efforts to the Firefox browser. Firefox 3+ supports all of Level 1, nearly all of Level 2, and some parts of Level 3. (The goal of the Mozilla development team was to build a 100 percent standards-compliant browser, and their work paid off.)

    DOM support became a huge priority for most browser vendors, and efforts have been ongoing to improve support with each release. The following table shows DOM support for popular browsers.

    NOTE The content of this compatibility table is changing all the time and should only be used as a historical reference.

    The Browser Object Model

    The Internet Explorer 3 and Netscape Navigator 3 browsers featured a Browser Object Model (BOM) that allowed access and manipulation of the browser window. Using the BOM, developers can interact with the browser outside of the context of its displayed page. What made the BOM truly unique, and often problematic, was that it was the only part of a JavaScript implementation that had no related standard. This changed with the introduction of HTML5, which sought to codify much of the BOM as part of a formal specification. Thanks to HTML5, a lot of the confusion surrounding the BOM has dissipated.

    Primarily, the BOM deals with the browser window and frames, but generally any browser-specific extension to JavaScript is considered to be a part of the BOM. The following are some such extensions:

    The capability to pop up new browser windows

    The capability to move, resize, and close browser windows

    The navigator object, which provides detailed information about the browser

    The location object, which gives detailed information about the page loaded in the browser

    The screen object, which gives detailed information about the user's screen resolution

    The performance object, which gives detailed information about the browser's memory consumption, navigational behavior, and timing statistics

    Support for cookies

    Custom objects such as XMLHttpRequest and Internet Explorer's ActiveXObject

    Because no standards existed for the BOM for a long time, each browser has its own implementation. There are some de facto standards, such as having a window object and a navigator object, but each browser defines its own properties and methods for these and other objects. With HTML5 now available, the implementation details of the BOM are expected to grow in a much more compatible way. A detailed discussion of the BOM is included in the chapter Browser Object Model.

    JAVASCRIPT VERSIONS

    Mozilla, as a descendant from the original Netscape, is the only browser vendor that has continued the original JavaScript version-numbering sequence. When the Netscape source code was spun off into an open-source project (named the Mozilla Project), the last browser version of JavaScript was 1.3. (As mentioned previously, version 1.4 was implemented on the server exclusively.) As the Mozilla Foundation continued work on JavaScript, adding new features, keywords, and syntaxes, the JavaScript version number was incremented. The following table shows the JavaScript version progression in Netscape/Mozilla browsers.

    The numbering scheme was based on the idea that Firefox 4 would feature JavaScript 2.0, and each increment in the version number prior to that point indicates how close the JavaScript implementation is to the 2.0 proposal. Though this was the original plan, the evolution of JavaScript happened in such a way that this was no longer possible. There is currently no target implementation for JavaScript 2.0, and this style of versioning ceased past the Firefox 4 release.

    NOTE It's important to note that only the Netscape/Mozilla browsers followed this versioning scheme. Internet Explorer, for example, has different version numbers for JScript. These JScript versions don't correspond whatsoever to the JavaScript versions mentioned in the preceding table. Furthermore, most browsers talk about JavaScript support in relation to their level of ECMAScript compliance and DOM support.

    SUMMARY

    JavaScript is a scripting language designed to interact with web pages and is made up of the following three distinct parts:

    ECMAScript, which is defined in ECMA-262 and provides the core functionality

    The Document Object Model (DOM), which provides methods and interfaces for working with the content of a web page

    The Browser Object Model (BOM), which provides methods and interfaces for interacting with the browser

    There are varying levels of support for the three parts of JavaScript across the five major web browsers (Internet Explorer, Firefox, Chrome, Safari, and Opera). Support for ECMAScript 5 is generally good across all browsers, and support for ECMAScript 6 and 7 is growing. Support for the DOM varies, but Level 3 compliance is increasingly normative. The BOM, codified in HTML5, can vary from browser to browser, though there are some commonalities that are assumed to be available.

    2

    JavaScript in HTML

    WHAT'S IN THIS CHAPTER?

    Using the

    Comparing inline and external scripts

    Examining how document modes affect JavaScript

    Preparing for JavaScript-disabled experiences

    The introduction of JavaScript into web pages immediately ran into the web's predominant language, HTML. As part of its original work on JavaScript, Netscape tried to figure out how to make JavaScript coexist in HTML pages without breaking those pages' rendering in other browsers. Through trial, error, and controversy, several decisions were finally made and agreed upon to bring universal scripting support to the web. Much of the work done in these early days of the web has survived and become formalized in the HTML specification.

    THE

    The primary method of inserting JavaScript into an HTML page is via the

    async—Optional. Indicates that the script should begin downloading immediately but should not prevent other actions on the page such as downloading resources or waiting for other scripts to load. Valid only for external script files.

    charset—Optional. The character set of the code specified using the src attribute. This attribute is rarely used because most browsers don't honor its value.

    crossorigin—Optional. Configures the CORS settings for the associated request; by default, CORS is not used at all. crossorigin=anonymous will configure the request for the file to not have the credentials flag set. crossorigin=use-credentials will set the credentials flag, meaning the outgoing request will include credentials.

    defer—Optional. Indicates that the execution of the script can safely be deferred until after the document's content has been completely parsed and displayed. Valid only for external scripts. Internet Explorer 7 and earlier also allow for inline scripts.

    integrity—Optional. Allows for verification of Subresource Integrity (SRI) by checking the retrieved resource against a provided cryptographic signature. If the signature of the retrieved resource does not match that specified by this attribute, the page will error and the script will not execute. This is useful for ensuring that a Content Delivery Network (CDN) is not serving malicious payloads.

    language—Deprecated. Originally indicated the scripting language being used by the code block (such as JavaScript, JavaScript1.2, or VBScript). Most browsers ignore this attribute; it should not be used.

    src—Optional. Indicates an external file that contains code to be executed.

    type—Optional. Replaces language; indicates the content type (also called MIME type) of the scripting language being used by the code block. Traditionally, this value has always been text/javascript, though both text/javascript and text/ecmascript are deprecated. JavaScript files are typically served with the application/x-javascript MIME type even though setting this in the type attribute may cause the script to be ignored. Other values that work in non–Internet Explorer browsers are application/javascript and application/ecmascript. If the value is module, the code is treated as an ES6 module and only then is eligible to use the import and export keywords.

    There are two ways to use the

    To include inline JavaScript code, place JavaScript code inside the

    The JavaScript code contained inside a

    When using inline JavaScript code, keep in mind that you cannot have the string anywhere in your code. For example, the following code causes an error when loaded into a browser:

    console.log(); }

    Because of the way that inline scripts are parsed, the browser sees the string as if it were the closing tag. This problem can be avoided easily by escaping the / character, as in this example:

    console.log(<\/script>); }

    The changes to this code make it acceptable to browsers and won't cause any errors.

    To include JavaScript from an external file, the src attribute is required. The value of src is a URL linked to a file containing JavaScript code, like this:

    In this example, an external file named example.js is loaded into the page. The file itself need only contain the JavaScript code that would occur between the opening tags. As with inline JavaScript code, processing of the page is halted while the external file is interpreted. (There is also some time taken to download the file.) In XHTML documents, you can omit the closing tag, as in this example:

    This syntax should not be used in HTML documents because it is invalid HTML and won't be handled properly by some browsers, most notably Internet Explorer.

    NOTE By convention, external JavaScript files have a .js extension. This is not a requirement because browsers do not check the file extension of included JavaScript files. This leaves open the possibility of dynamically generating JavaScript code using a server-side scripting language, or for in-browser transpilation into JavaScript from a JavaScript extension language such as TypeScript or React's JSX. Keep in mind, though, that servers often use the file extension to determine the correct MIME type to apply to the response. If you don't use a .js extension, double-check that your server is returning the correct MIME type.

    It's important to note that a tags. If both are provided, the script file is downloaded and executed while the inline code is ignored.

    One of the most powerful and most controversial parts of the

    When the browser goes to resolve this resource, it will send a GET request to the path specified in the src attribute to retrieve the resource—presumably a JavaScript file. This initial request is not subject to the browser's cross-origin restrictions, but any JavaScript returned and executed will be. Of course, this request is still subject to the HTTP/HTTPS protocol of the parent page.

    Code from an external domain will be loaded and interpreted as if it were part of the page that is loading it. This capability allows you to serve up JavaScript from various domains, if necessary. Be careful, however, if you are referencing JavaScript files located on a server that you don't control. A malicious programmer could, at any time, replace the file. When including JavaScript files from a different domain, make sure you are the domain owner or the domain is owned by a trusted source. The

    Regardless of how the code is included, the

    Tag Placement

    Traditionally, all

    Example HTML Page

    The main purpose of this format was to keep external file references, both CSS files and JavaScript files, in the same area. However, including all JavaScript files in the of a document means that all of the JavaScript code must be downloaded, parsed, and interpreted before the page begins rendering (rendering begins when the browser receives the opening tag). For pages that require a lot of JavaScript code, this can cause a noticeable delay in page rendering, during which time the browser will be completely blank. For this reason, modern web applications typically include all JavaScript references in the element, after the page content, as shown in this example:

    Example HTML Page

    Using this approach, the page is completely rendered in the browser before the JavaScript code is processed. The resulting user experience is perceived as faster because the amount of time spent on a blank browser window is reduced.

    Deferred Scripts

    HTML 4.01 defines an attribute named defer for the

    Example HTML Page

    Even though the

    As mentioned previously, the defer attribute is supported only for external script files. This was a clarification made in HTML5, so browsers that support the HTML5 implementation will ignore defer when set on an inline script. Internet Explorer 4–7 all exhibit the old behavior, while Internet Explorer 8 and above support the HTML5 behavior.

    Support for the defer attribute was added beginning with Internet Explorer 4, Firefox 3.5, Safari 5, and Chrome 7. All other browsers simply ignore this attribute and treat the script as it normally would. For this reason, it's still best to put deferred scripts at the bottom of the page.

    NOTE For XHTML documents, specify the defer attribute as defer=defer.

    Asynchronous Scripts

    HTML5 introduces the async attribute for

    Example HTML Page

    In this code, the second script file might execute before the first, so it's important that there are no dependencies between the two. The purpose of specifying an async script is to indicate that the page need not wait for the script to be downloaded and executed before continuing to load, and it also need not wait for another script to load and execute before it can do the same. Because of this, it's recommended that asynchronous scripts not modify the DOM as they are loading.

    Asynchronous scripts are guaranteed to execute before the page's load event and may execute before or after DOMContentLoaded (see the Events chapter for details). Firefox 3.6, Safari 5, and Chrome 7 support asynchronous scripts. Using async scripts also confers to your page the implicit assumption that you do not intend to use document.write—but good web development practices dictate that you shouldn't be using it anyway.

    NOTE For XHTML documents, specify the async attribute as async=async.

    Dynamic Script Loading

    You are not limited to using static

    let script = document.createElement('script'); script.src = 'gibberish.js'; document.head.appendChild(script);

    Of course, this request will not be generated until the HTMLElement is attached to the DOM, and therefore not until this script itself runs. By default, scripts that are created in this fashion are async. This can be problematic, however, as all browsers support createElement but not all support async script requests. Therefore, to unify the dynamic script loading behavior, you can explicitly mark the tag as synchronous:

    let script = document.createElement('script'); script.src = 'gibberish.js'; script.async = false; document.head.appendChild(script);

    Resources fetched in this fashion will be hidden from browser preloaders. This will severely injure their priority in the resource fetching queue. Depending on how your application works and how it is used, this can severely damage performance. To inform preloaders of the existence of these dynamically requested files, you can explicitly declare them in the document head:

    subresource href=gibberish.js>

    Changes in XHTML

    Extensible HyperText Markup Language, or XHTML, is a reformulation of HTML as an application of XML. Unlike in HTML, where the type attribute is unneeded when using JavaScript, in XHTML, the

    The rules for writing code in XHTML are stricter than those for HTML, which affects the

    In HTML, the

    There are two options for fixing the XHTML syntax error. The first is to replace all occurrences of the less-than symbol (<) with its HTML entity (<). The resulting code looks like this:

    if (a < b) {   console.log(A is less than B);   } else if (a> b) {   console.log(A is greater than B);   } else {   console.log(A is equal to B);   } }

    This code will now run in an XHTML page; however, the code is slightly less readable. Fortunately, there is another approach.

    The second option for turning this code into a valid XHTML version is to wrap the JavaScript code in a CDATA section. In XHTML (and XML), CDATA sections are used to indicate areas of the document that contain free-form text not intended to be parsed. This enables you to use any character, including the less-than symbol, without incurring a syntax error. The format is as follows:

    function compare(a, b) {   if (a < b) {   console.log(A is less than B);   } else if (a> b) {   console.log(A is greater than B);   } else {   console.log(A is equal to B);   } } ]]>

    In XHTML-compliant web browsers, this solves the problem. However, many browsers are still not XHTML-compliant and don't support the CDATA section. To work around this, the CDATA markup must be offset by JavaScript comments:

    //function compare(a, b) {   if (a < b) {   console.log(A is less than B);   } else if (a> b) {   console.log(A is greater than B);   } else {   console.log(A is equal to B);   } } //]]>

    This format works in all modern browsers. Though a little bit of a hack, it validates as XHTML and degrades gracefully for pre-XHTML browsers.

    NOTE XHTML mode is triggered when a page specifies its MIME type as application/xhtml+xml. Not all browsers officially support XHTML served in this manner.

    Deprecated Syntax

    Since Netscape 2 was released in 1995, all browsers have used JavaScript as their default programming language. The type attribute uses a MIME type string to identify the contents of

    When the

    Netscape worked with Mosaic to come up with a solution that would hide embedded JavaScript code from browsers that didn't support it. The final solution was to enclose the script code in an HTML comment, like this:

    function sayHi(){   console.log(Hi!); } //-->

    Using this format, browsers like Mosaic would safely ignore the content inside of the

    Although this format is still recognized and interpreted correctly by all web browsers, it is no longer necessary and should not be used. In XHTML mode, this also causes the script to be ignored because it is inside a valid XML comment.

    INLINE CODE VERSUS EXTERNAL FILES

    Although it's possible to embed JavaScript in HTML files directly, it's generally considered a best practice to include as much JavaScript as possible using external files. Keeping in mind that there are no hard and fast rules regarding this practice, the arguments for using external files are as follows:

    Maintainability—JavaScript code that is sprinkled throughout various HTML pages turns code maintenance into a problem. It is much easier to have a directory for all JavaScript files so that developers can edit JavaScript code independent of the markup in which it's used.

    Caching—Browsers cache all externally linked JavaScript files according to specific settings, meaning that if two pages are using the same file, the file is downloaded only once. This ultimately means faster page-load times.

    Future-proof—By including JavaScript using external files, there's no need to use the XHTML or comment hacks mentioned previously. The syntax to include external files is the same for both HTML and XHTML.

    One notable consideration when configuring how external files are requested is their implication on request bandwidth. With SPDY/HTTP2, the per-request overhead is substantially reduced insofar as it may be advantageous to deliver scripts to the client as lightweight independent JavaScript components.

    For example, your first page might have the following:

    A subsequent page loaded might have the following:

    On the initial request, if the browser supports SPDY/HTTP2, it will be able to efficiently retrieve a number of files from the same endpoint, and it will enter them into the browser cache on a per-file basis. From the perspective of the browser, retrieval of these individual resources over SPDY/HTTP2 should have approximately the same latency as delivering a monolithic JavaScript payload.

    On the second page request, because you segmented your application into lightweight cacheable files, some of the components that the second page also depends upon are already in the browser cache.

    Of course, this assumes the browser supports SPDY/HTTP2, which is only a valid assumption for modern browsers. Monolithic payloads may be more appropriate if your aim is to include support for older browsers.

    DOCUMENT MODES

    Internet Explorer 5.5 introduced the concept of document modes through the use of doctype switching. The first two document modes were quirks mode, which made Internet Explorer behave as if it were version 5 (with several nonstandard features) and standards mode, which made Internet Explorer behave in a more standards-compliant way. Though the primary difference between these two modes is related to the rendering of content with regard to CSS, there are also several side effects related to JavaScript. These side effects are discussed throughout the book.

    Since Internet Explorer first introduced the concept of document modes, other browsers have followed suit. As this adoption happened, a third mode called almost standards mode arose. That mode has a lot of the features of standards mode but isn't as strict. The main difference is in the treatment of spacing around images (most noticeable when images are used in tables).

    Quirks mode is achieved in all browsers by omitting the doctype at the beginning of the document. This is considered poor practice because quirks mode is very different across all browsers, and no level of true browser consistency can be achieved without hacks.

    Standards mode is turned on when one of the following doctypes is used:

    -//W3C//DTD HTML 4.01//EN http://www.w3.org/TR/html4/strict.dtd>       -//W3C//DTD XHTML 1.0 Strict//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd>

    Almost standards mode is triggered by transitional and frameset doctypes, as follows:

    -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd>       -//W3C//DTD HTML 4.01 Frameset//EN http://www.w3.org/TR/html4/frameset.dtd>       -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>       -//W3C//DTD XHTML 1.0 Frameset//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd>

    Because almost standards mode is so close to standards mode, the distinction is rarely made. People talking about standards mode may be talking about either, and detection for the document mode (discussed later in this book) also doesn't make the distinction. Throughout this book, the term standards mode should be taken to mean any mode other than quirks.

    THE

    Of particular concern to early browsers was the graceful degradation of pages when the browser didn't support JavaScript. To that end, the

    The

    The browser doesn't support scripting.

    The browser's scripting support is turned off.

    If either of these conditions is met, then the content inside the

    Here is a simple example:

    Example HTML Page  

    This page requires a JavaScript-enabled browser.

    In this example, a message is displayed to the user when the scripting is not available. For scripting-enabled browsers, this message will never be seen even though it is still a part of the page.

    SUMMARY

    JavaScript is inserted into HTML pages by using the

    To include external JavaScript files, the src attribute must be set to the URL of the file to include, which may be a file on the same server as the containing page or one that exists on a completely different domain.

    Enjoying the preview?
    Page 1 of 1