In this chapter I provide a quick tour of the most important basic features of the JavaScript language as they apply to Angular development. I don’t have the space to describe JavaScript completely, so I have focused on the essentials that you’ll need to get up to speed and follow the examples in this book. In Chapter 6, I describe some of the more advanced JavaScript features that you will need and some of the additional features provided by TypeScript.
The JavaScript language is managed through a standard process that defines new features. Modern browsers have started to implement features from the ECMAScript 6 (also known as ES6) standard, and ECMAScript 7 (ES7) is making its way into service as I write this. The new standards broaden the features available to JavaScript developers and make using JavaScript more consistent with more conventional languages such as C# or Java.
Modern browsers update themselves, which means that a Google Chrome user, for example, is likely to have a recent release of the browser that implements at least some of the most recent JavaScript features. Sadly, older browsers that don’t update themselves are still in widespread use, which means you can’t rely on modern features being available for use in your application.
Chapter Summary
Problem | Solution | Listing |
---|---|---|
Create JavaScript functionality | Use JavaScript statements | 5 |
Create groups of statements that are executed on command | Use functions | 6, 7, 10–12 |
Define functions that can handle more or fewer arguments than parameters | Use default or rest parameters | 8, 9 |
Express functions more concisely | Use arrow functions | 13 |
Store values and objects for later use | Declare variables using the let or var keyword | 14–16 |
Store basic data values | Use the JavaScript primitive types | 17–20 |
Control the flow of JavaScript code | Use conditional statements | 21 |
Determine whether two objects or values are the same | Use the quality and identity operators | 22–23 |
Explicitly convert types | Use the to<type> methods | 24–26 |
Store related objects or values together in sequence | Use an array | 27–33 |
USING “PLAIN” JAVASCRIPT FOR ANGULAR
When Angular 2 was introduced, the use of TypeScript was optional, and it was possible to write Angular applications using plain JavaScript. The result was awkward and required some contorted code to re-create the effect of key TypeScript features, but it was possible, and Google provided a complete set of API documents for both TypeScript and plain JavaScript developers.
The support for working with plain JavaScript development has been reduced with each subsequent release, with the effect that there is no guidance for programmers who are reluctant to adopt TypeScript.
My advice is to embrace the complete Angular experience, even though it can take some time and effort to master TypeScript. The result will be a better development experience, containing code that is more concise, easier to read, and simpler to maintain. This is the approach I have taken in this book, and every example assumes that this is the path you are following.
Preparing the Example Project
To create the example project for this chapter, open a new command prompt, navigate to a convenient location, and run the command shown in Listing 5-1.
Tip
You can download the example project for this chapter—and for all the other chapters in this book—from https://github.com/Apress/pro-angular-6 .
Creating the Example Project
This command creates a project called JavaScriptPrimer that is set up for Angular development. I don’t do any Angular development in this chapter, but I am going to use the Angular development tools as a convenient way to demonstrate different JavaScript and TypeScript features. To prepare, I replaced the contents of the main.ts file in the src folder with the single JavaScript statement shown in Listing 5-2.
Tip
Pay attention to the extension of the file. Even though this chapter uses only JavaScript features, it relies on the TypeScript compiler to convert them into code that will run in any browser. That means the .ts file must be used, which then allows the TypeScript compiler to create the corresponding .js file that will be used by the browser.
Replacing the Contents of the main.ts File in the src Folder
Starting the Development Tools
Understanding the Basic Workflow
Adding a Statement in the main.ts File in the src Folder
- 1.
The TypeScript compiler will detect the change to the main.ts file and compile it to generate a new main.js file that can run in any browser. The code that is produced is combined with the other JavaScript code produced by the compiler into a single file called a bundle.
- 2.
The development HTTP server detects the change to the bundle file and signals the browser to reload the HTML document.
- 3.
The browser reloads the HTML document and starts processing the elements it contains. It loads the JavaScript files specified by the script elements in the HTML document, including one that specifies the bundle file that contains the statements from the main.ts file.
- 4.
The browser executes the statements that were originally in the main.ts file, which writes out two messages to the browser’s JavaScript console.
This may seem like a large number of steps for a simple application, but this process allows TypeScript features to be used and automatically takes care of detecting changes, running the compiler, and updating the browser.
Using Statements
Adding JavaScript Statements in the main.ts File in the src Folder
Defining and Using Functions
When the browser receives JavaScript code, it executes the statements it contains in the order in which they have been defined. This is what happened in the previous example. The browser loader loaded the main.js file, and the statements it contains were executed one by one, all of which wrote a message to the console.
Defining a JavaScript Function in the main.ts File in the src Folder
Defining a function simple: use the let keyword followed by the name you want to give the function, followed by the equal sign (=) and the function keyword, followed by parentheses (the ( and ) characters). The statements you want the function to contain are enclosed between braces (the { and } characters).
Other than demonstrating how functions are defined, this example isn’t especially useful because the function is invoked immediately after it has been defined. Functions are much more useful when they are invoked in response to some kind of change or event, such as user interaction.
THE OTHER WAY TO DEFINE FUNCTIONS
This code will generate an error reporting that myFunc is not a function. Developers who are new to JavaScript tend to prefer using function declarations because the syntax is more consistent with languages like C# or Java. The technique you use is entirely up to you, although you should aim to be consistent throughout your project to make your code easier to understand.
Defining Functions with Parameters
Defining Functions with Parameters in the main.ts File in the src Folder
Using Default and Rest Parameters
The number of arguments you provide when you invoke a function doesn’t need to match the number of parameters in the function. If you call the function with fewer arguments than it has parameters, then the value of any parameters you have not supplied values for is undefined, which is a special JavaScript value. If you call the function with more arguments than there are parameters, then the additional arguments are ignored.
The consequence of this is that you can’t create two functions with the same name and different parameters and expect JavaScript to differentiate between them based on the arguments you provide when invoking the function. This is called polymorphism, and although it is supported in languages such as Java and C#, it isn’t available in JavaScript. Instead, if you define two functions with the same name, then the second definition replaces the first.
Using a Default Parameter in the main.ts File in the src Folder
Using a Rest Parameter in the main.ts File in the src Folder
Defining Functions That Return Results
Returning a Result from a Function in the main.ts File in the src Folder
Using Functions As Arguments to Other Functions
Using a Function as an Arguments to Another Function in the main.ts File
Chaining Functions Calls in the main.ts File in the src Folder
This example produces the same result as Listing 5-11.
Using Arrow Functions
Using Arrow Functions in the main.ts File in the src Folder
These functions perform the same work as the ones in Listing 5-12. There are three parts to an arrow function: the input parameters, then an equal sign and a greater-than sign (the “arrow”), and finally the function result. The return keyword and curly braces are required only if the arrow function needs to execute more than one statement. There are more examples of arrow functions later in this chapter.
Using Variables and Types
Using let to Declare Variables in the main.ts File in the src Folder
Using var to Declare Variables in the main.ts File in the src Folder
The problem is that the var keyword creates variables whose scope is the containing function, which means that all the references to message are referring to the same variable. This can cause unexpected results for even experienced JavaScript developers and is the reason that the more conventional let keyword was introduced.
USING LET AND CONST
The let keyword is used to define a variable, and the const keyword is used to define a constant value that will not change. It is good practice to use the const keyword for any value that you don’t expect to modify so that you receive an error if any modifications are attempted. This is a practice that I rarely follow, however—in part because I am still adapting to not using the var keyword and in part because I write code in a range of languages and there are some features that I avoid because they trip me up when I switch from one to another. If you are new to JavaScript, then I recommend trying to use const and let correctly and avoiding following my poor behavior.
Using Variable Closure
Using Variable Closure in the main.ts File in the src Folder
Using the Primitive Types
JavaScript defines a basic set of primitive types: string, number, and boolean. This may seem like a short list, but JavaScript manages to fit a lot of flexibility into these three types.
Tip
I am simplifying here. There are three other primitives that you may encounter. Variables that have been declared but not assigned a value are undefined, while the null value is used to indicate that a variable has no value, just as in other languages. The final primitive type is Symbol, which is an immutable value that represents a unique ID but that is not widely used at the time of writing.
Working with Booleans
Defining boolean Values in the main.ts File in the src Folder
Working with Strings
Defining string Variables in the main.ts File in the src Folder
Useful string Properties and Methods
Name | Description |
---|---|
length | This property returns the number of characters in the string. |
charAt(index) | This method returns a string containing the character at the specified index. |
concat(string) | This method returns a new string that concatenates the string on which the method is called and the string provided as an argument. |
indexOf(term, start) | This method returns the first index at which term appears in the string or -1 if there is no match. The optional start argument specifies the start index for the search. |
replace(term, newTerm) | This method returns a new string in which all instances of term are replaced with newTerm. |
slice(start, end) | This method returns a substring containing the characters between the start and end indices. |
split(term) | This method splits up a string into an array of values that were separated by term. |
toUpperCase() toLowerCase() | These methods return new strings in which all the characters are uppercase or lowercase. |
trim() | This method returns a new string from which all the leading and trailing whitespace characters have been removed. |
Using Template Strings
Using a Template String in the main.ts File
Working with Numbers
Defining number Values in the main.ts File in the src Folder
You don’t have to specify which kind of number you are using. You just express the value you require, and JavaScript will act accordingly. In the listing, I have defined an integer value, defined a floating-point value, and prefixed a value with 0x to denote a hexadecimal value.
Using JavaScript Operators
Useful JavaScript Operators
Operator | Description |
---|---|
++, -- | Pre- or post-increment and decrement |
+, -, *, /, % | Addition, subtraction, multiplication, division, remainder |
<, <=, >, >= | Less than, less than or equal to, more than, more than or equal to |
==, != | Equality and inequality tests |
===, !== | Identity and nonidentity tests |
&&, || | Logical AND and OR (|| is used to coalesce null values) |
= | Assignment |
+ | String concatenation |
?: | Three-operand conditional statement |
Using Conditional Statements
Using the if/else and switch Conditional Statements in the main.ts File
The Equality Operator vs. the Identity Operator
Using the Equality Operator in the main.ts File in the src Folder
Using the Identity Operator in the main.ts File in the src Folder
Explicitly Converting Types
String Concatenation Operator Precedence in the main.ts File
The second result is the kind that causes confusion. What might be intended to be an addition operation is interpreted as string concatenation through a combination of operator precedence and over-eager type conversion. To avoid this, you can explicitly convert the types of values to ensure you perform the right kind of operation, as described in the following sections.
Converting Numbers to Strings
Using the number.toString Method in the main.ts File in the src Folder
Useful Number-to-String Methods
Method | Description |
---|---|
toString() | This method returns a string that represents a number in base 10. |
toString(2)toString(8)toString(16) | This method returns a string that represents a number in binary, octal, or hexadecimal notation. |
toFixed(n) | This method returns a string representing a real number with the n digits after the decimal point. |
toExponential(n) | This method returns a string that represents a number using exponential notation with one digit before the decimal point and n digits after. |
toPrecision(n) | This method returns a string that represents a number with n significant digits, using exponential notation if required. |
Converting Strings to Numbers
Converting Strings to Numbers in the main.ts File in the src Folder
Useful String to Number Methods
Method | Description |
---|---|
Number(str) | This method parses the specified string to create an integer or real value. |
parseInt(str) | This method parses the specified string to create an integer value. |
parseFloat(str) | This method parses the specified string to create an integer or real value. |
Working with Arrays
Creating and Populating an Array in the main.ts File in the src Folder
I have created a new array by calling new Array(). This creates an empty array, which I assign to the variable myArray. In the subsequent statements, I assign values to various index positions in the array. (There is no console output from this listing.)
There are a couple of things to note in this example. First, I didn’t need to declare the number of items in the array when I created it. JavaScript arrays will resize themselves to hold any number of items. The second point is that I didn’t have to declare the data types that the array will hold. Any JavaScript array can hold any mix of data types. In the example, I have assigned three items to the array: a number, a string, and a boolean.
Using an Array Literal
Using the Array Literal Style in the main.ts File in the src Folder
In this example, I specified that the myArray variable should be assigned a new array by specifying the items I wanted in the array between square brackets ([ and ]). (There is no console output from this listing.)
Reading and Modifying the Contents of an Array
Reading the Data from an Array Index in the main.ts File in the src Folder
Modifying the Contents of an Array in the main.ts File in the src Folder
Enumerating the Contents of an Array
Enumerating the Contents of an Array in the main.ts File in the src Folder
The JavaScript for loop works just the same way as loops in many other languages. You determine how many elements there are in the array by using the length property.
Using the Spread Operator
Using the Spread Operator in the main.ts File in the src Folder
Using the Built-in Array Methods
Useful Array Methods
Method | Description |
---|---|
concat(otherArray) | This method returns a new array that concatenates the array on which it has been called with the array specified as the argument. Multiple arrays can be specified. |
join(separator) | This method joins all the elements in the array to form a string. The argument specifies the character used to delimit the items. |
pop() | This method removes and returns the last item in the array. |
shift() | This method removes and returns the first element in the array. |
push(item) | This method appends the specified item to the end of the array. |
unshift(item) | This method inserts a new item at the start of the array. |
reverse() | This method returns a new array that contains the items in reverse order. |
slice(start,end) | This method returns a section of the array. |
sort() | This method sorts the array. An optional comparison function can be used to perform custom comparisons. |
splice(index, count) | This method removes count items from the array, starting at the specified index. The removed items are returned as the result of the method. |
unshift(item) | This method inserts a new item at the start of the array. |
every(test) | This method calls the test function for each item in the array and returns true if the function returns true for all of them and false otherwise. |
some(test) | This method returns true if calling the test function for each item in the array returns true at least once. |
filter(test) | This method returns a new array containing the items for which the test function returns true. |
find(test) | This method returns the first item in the array for which the test function returns true. |
findIndex(test) | This method returns the index of the first item in the array for which the test function returns true. |
foreach(callback) | This method invokes the callback function for each item in the array, as described in the previous section. |
includes(value) | This method returns true if the array contains the specified value. |
map(callback) | This method returns a new array containing the result of invoking the callback function for every item in the array. |
reduce(callback) | This method returns the accumulated value produced by invoking the callback function for every item in the array. |
Processing a Data Array in the main.ts File in the src Folder
Summary
In this chapter, I provided a brief primer on the JavaScript, focusing on the core functionality that will get you started with the language. Some of the features that I described in this chapter are recent additions to the JavaScript specification and require the TypeScript compiler to convert them to code that can run in older browsers. I continue this theme in the next chapter and introduce some of the more advanced JavaScript features that are used in Angular development.