Rediscovering javascript pdf download
Hands down, one of the most exciting features of JavaScript is destructuring. JavaScript has supported classes for a long time, but without the class keyword. Sadly, that created problems. Unlike many other languages that support class-based inheritance, JavaScript has prototypal inheritance. Even though this feature is highly powerful and flexible, using it has been hard in the past—with the syntax confusing and error prone. Asynchronous programming is a way of life in JavaScript, and you need a fairly good knowledge of how promises work to master that.
Chapter 10, Keeping Your Promises, on page , has you covered, I promise. Then, in Chapter 12, Deep Dive into Metaprogramming, on page , we dig into another type of metaprogramming—synthesis—and how to create highly dynamic code. Finally, for your convenience, the URLs that are scattered throughout this book are gathered in one place in Appendix 2, Web Resources, on page Who Is This Book For?
This book is for programmers, full-stack developers, lead developers, software architects, technical managers, or just about anyone who dives into code and is interested in learning and applying modern JavaScript. You can make use of these features to program the front or the back end using JavaScript. This book assumes the reader is familiar with basics of programming—it does not teach the fundamentals of programming. Some prior knowledge of JavaScript will be helpful. Programmers who are familiar with languages like Java, C , and Python but who are not familiar with JavaScript should be able to pick up the concepts presented fairly quickly.
Online Resources You can download all the example source code for the book from the Pragmatic Bookshelf website for this book. Thank you for reading this book. Yet, these fundamental operations were error prone in the past. In this part we explore the safe alternatives modern JavaScript offers for defining variables and passing arguments.
Knowing these first will help you stay clear of common pitfalls when coding in JavaScript. JavaScript is not one of them—semicolons are not optional.
Merely placing a ; is not sufficient. A valid program ends with a ;. If a given script does not end with a ;, then JavaScript inserts a ; automatically. As the tokens are parsed from left to right, if an unexpected token is encountered and a line break separates it from the previous token, then a ; is automatically inserted before the encountered token. The bad part of the code, however, is that the token second is not expected after first, even though a line break separates the two.
So, JavaScript quietly inserts a ; before the variable second. This results in first taking on a value of undefined and the variable second turning into a global variable—ouch.
We can see this from the output: undefined 1 1 If a candidate token is break, continue, return, throw, or yield, and a line break appears between the candidate token and the next token, then JavaScript automatically inserts a ; after the candidate token. If a line is relatively short, end it with a clearly visible semicolon. If a line is long, then break it into multiple lines, but do so in such a way that JavaScript does not deviate from your intentions by automatically placing semicolons.
One value is of number type and the other two are of string type. The last three lines compare each combination of the constants. Suppose a is equal to b and b is equal to c; then logically JavaScript should tell us that a is equal to c.
If the objects or values being compared are both of type string, number, or boolean, then a direct equality check is performed. When comparing a with b and b with c, type coercion was involved before the comparison. However, when a and c were compared, a lexical comparison was used. Hence we see a different result than what we may otherwise expect. In most of the situations, however, we generally would want a straight up strict equality check, with no type coercions.
As expected, the effect of calling oops will be to print the value 2 to the console. Lemme make it global. To verify this, at line 9, after the call to oops , we print the variable that was used inside the oops function. The output from the code shows the consequences of not declaring the variable before using it—it is indeed global. Mistyping a variable name creates an unintended global variable.
Once a variable becomes global, its reach can have terrible consequences. Finally we append to the result the string after the last expression in the template literal. Try changing the template literal passed to the mask tag to different values—an empty template literal, one with no expressions, one with only expressions, expressions that are numbers, and so forth.
Since tags may transform template literals into various representations, the possibilities of its application is endless.
Different JavaScript libraries may use tags for different purposes. Enhanced Object Literals Creating an object by assigning fields with values from existing variables is a common operation. In the past this involved a lot of noisy code. It assigns the value of name to a property with the same name and likewise assigns age to age.
Finally, it creates a computed property whose name is based on the value of the sport parameter. This last step had to be done outside of the initialization in the past—computed properties were not allowed in the object initialization list. The object literals syntax makes it possible to assign values to fields and create functions within an object.
Enhanced object literal enhances that notation by removing some noise and making a few things implicit. Shorthand Assignment Notation If the name of a field is the same as a variable in the lexical scope, for example, name: name, then we can remove the colon and what follows after the colon.
In other words, within an object literal, name means name: name. The value of the name field is set to the value of the parameter with the same name. Likewise, the value of age is set to the value of the parameter with the same name. Drop in the function name followed by the parameter list and write the body of the desired function. The method toString belongs to the instance—that is, each instance created using the createPerson function will have its own function. Instead of creating a function internally, we can receive and share a function by storing it into a property, as we did with sportFn assigned to the computed property playSoccer.
Computed Properties in Object Literals The computed properties, like playSoccer—whose name is computed based on the value of a variable—are no longer forced to be outside of object initialization.
Computed properties are first-class citizens and may appear around other members in object initialization, thanks to enhanced object literal. In addition, each line of code also saw some reduction in noise. Less typing, less boilerplate code, for the win. Destructuring Destructuring is an elegant way to extract data from arrays and objects. It removes excessive and repetitive use of indexing operators or dots to get to the data within arrays and objects.
Array Destructuring Functions typically return a single value: a primitive or an object. There is no elegant way to return multiple values other than returning an array. That makes the code within the function easy to write, but it turns the code on the receiving end messy. The code is neither fluent nor intuitive.
It would be nice to assign the result to variables like firstName and lastName without having to use the index operator; destructuring makes that possible. We did not need the temporary garbage variable president6, and there was no need for the indexing operator. Instead of const, we may define the variables as let as well. More generally, we can extract only the specific values we care about and ignore the ones in the positions in between using an empty argument. Extracting More than Available Values We saw examples of extracting all the values and also extracting fewer values than available.
Since there are only three values, the variable nickName is assigned a value of undefined. Providing a Default Value We got undefined when we asked for an extra value to be extracted. Remember, from Defining Default Values for Parameters, on page 34, a parameter picks up a default value if the argument is undefined. We can apply that feature here to substitute a default value if a value being extracted is undefined. Extracting into Existing Variable and Swapping We can use the destructuring feature to swap two values.
This eliminates the need for a temporary variable to store the values while we move them around. It also avoids the extra lines of code often used to swap. This example also illustrated how to extract values into existing variables.
Existing variables may be assigned values from extraction using the same syntax of destructuring. We can also extract values in the parameter list from the arguments passed to a function. Less noise, more elegant. Destructuring is one of the most powerful features of modern JavaScript. Its power extends beyond arrays. Object Destructuring Enhanced object literals that we saw earlier in this chapter provided a nice way to create an object using values from variables in lexical scope.
Object destructuring is the opposite—it provides an elegant way to extract data from objects into variables in local or lexical scope. Suppose we have an object that holds the details of a person. The object property list ends with a comma. In the past, to add a new property to an object or a new element to an array, we had to first locate the current last item and place a comma before entering the new item, possibly on a new line.
Now, with the ability to end the last item with a comma, we can jump right into the next line and key in the next new item. JavaScript now allows arrays, object literals, parameter lists, and argument lists to end with comma.
A small feature for the language—a lot of joy for the programmers! Destructuring can reduce a lot of that cruft. Destructuring Objects The destructuring syntax for objects is a bit different from the one we used for arrays; after all, the properties of objects are not positional but referenced using property names.
If the syntax looks a bit strange, be assured it is. Instead of thinking of it as extraction, think of it as pattern matching. For every property with the same name on both sides, we compare the values and determine that the variable X should be the value for b on the right side. As a result, firstName is given the value Sam. Likewise, age, which is mapped to theAge, is given the value 2. Extracting to Variables with the Same Name In the previous example, we extracted name into firstName.
The name variable is initialized with the value Sam of the name property whereas the theAge variable is initialized with the value of the age property. Extracting Computed Properties In addition to the simple property names like name, age, and height, the object we created also has computed properties: [weight] and [Symbol.
In the example, wt is assigned the value of the computed property [weight] and favColor is assigned the value of the Symbol property, respectively. Assigning Default Values When extracting, if a property we ask for is not present, we can assign a default value for the missing property. If the value is not present, the default value assigned to the property on the left-hand side kicks in. The favorite variable takes on a value of true. If, for instance, we wanted to access the age property multiple times in the function, then we would either have to use person.
Using the object destructuring syntax, we can combine parameter declaration with object value extraction. However, during the invocation of the function, the two desired properties name and age are extracted into the variables theName and theAge. In addition, the street property that is nested within the address property is extracted.
Use caution; this syntax defines only two variables, name and street. It does not define the address variable. Dealing with Collisions We managed to extract the street property from address, but what if we wanted to extract the street properties from both address and shipping?
The problem is not the extraction part, but that it will not make sense to assign two values simultaneously to a single variable. Thus we have to provide two different local variable names. We can keep the variable the same as the property for one of the properties and assign a different name for the other.
Alternatively, we can provide a different variable name than the property name for both properties. We are not limited to extracting into new variables. We can extract and assign to existing variables in local or lexical scope. The semicolon should be outside the. Extracting with … In the examples so far, we have extracted part of the object, leaving behind some properties. Sometimes we want to copy the whole object, and at the same time, maybe add new properties, or change the values of existing properties.
Destructuring can do this quite well. As an example, the popular JavaScript state container library Redux1 is based on immutable state. Instead of modifying existing objects, it transforms them into new objects. In addition, 1. If the given person object already has an age property, the copy will have a different value. The intent of the addAge function was to either add or replace the age property in the copy while retaining all the other properties.
The code, as written, is not extensible. If we add another property—for example, email—to the person, the addAge function will not bring that over. Also, if we remove an existing property, the code will produce an unintended result—the copied object will have an undesirable value of undefined for the removed property.
In this example, we replace the last property and at the same time add a new age property. If the intent is to keep all the current properties of an object while replacing the values of some and optionally adding a few new properties, then rely on the spread operator instead of specifying each property by name.
This is critical from the extensibility point of view and will minimize the need to track down bugs later on. Wrapping Up Template literals and destructuring greatly reduce the noise in code and are among the most charming features in modern JavaScript. Furthermore, tagged templates offer the ability to process literals to implement custom logic.
Object literals reduce the ceremony around creating objects, and powerful destructuring makes extracting data from arrays and objects pretty darn easy. Furthermore, mixing destructuring with the rest operator makes the code for copying objects extensible to adding and removing properties.
Exercises Literals and destructuring are some of the most powerful features of JavaScript, but they come with some idiosyncrasies. The following practice exercises will help you hone the concepts. You can find answers to these exercises on page Sara console. Also, the tagged template should convert all expressions to uppercase. In addition to working with functions, you can reach for the full power of object-oriented programming when you need it.
Also, modules provide a nice way to divide the code into files with cohesive code and then intermix them in a logical and meaningful fashion. In the past, you may have found object-oriented OO programming in JavaScript rather primitive, especially if you were familiar with other mainstream languages.
Even today, many programmers still think that JavaScript has little to do with OO programming. One of the main reasons for that is that the old syntax and semantics of working with classes were very confusing and error-prone. By the end of this chapter you will be able to not only freely use classes, but also mix the functional programming style from Chapter 5, Arrow Functions and Functional Style, on page 69 with the OO style we focus on here.
Creating a Class Classes are the most fundamental part of OO programming, and yet, in the earlier versions, JavaScript did not have an explicit keyword to define classes.
It was never clear if we were working with a class or a function. Serious OO programming requires more rigorous syntax and a clearer specification for creating and using classes. Modern JavaScript delivers that quite well, fortunately. Out with the Old Way To create a class, we used to write a constructor function. The constructor looked much like any other function in syntax. To tell the difference between a regular function and a constructor, we relied on programmers following the convention to capitalize the function name.
While function car is considered a function, function Car is considered a constructor. It was not clear how to define the members of a class. Another problem was that there was nothing to stop someone from placing a new before a function, like new car , or invoking a constructor as a function, like Car. Accidentally using a piece of code in ways other than it was intended is a source of error and a huge time sink.
What about inheritance? And how do we override a method? Do we use this. Coding that is a form of cruel and unusual punishment. Not only was the syntax unclear, the approach was verbose and highly error prone. Enough of that—out with the horrific old, in with the new, enriched, pleasant syntax. The class is available for use only after the point of definition in the execution flow. Creating a class defines a no-parameter default constructor, which appears to be empty bodied.
But you may want to execute some code as part of object construction. For that we need to define an explicit constructor. This reveals the default constructor that JavaScript quietly created for us: [ 'constructor' ] We may provide an implementation or body for the constructor if we like. The body of the constructor may initialize fields, like this.
The output of the previous code shows that the constructor initialized the this. If you want to initialize some fields or perform some actions when an instance is created, then write a constructor. Defining a Method Methods are an integral part of classes. They exhibit behavior and are often used to perform some action, and possibly to effect state change. In the drive method we increase the this. A method may take zero, one, or more parameters, including default and rest parameters. Methods may access and modify any fields of the class and may perform actions.
They may also access any variable in their scope and invoke functions in their scope, including other methods of the instance. However, unlike in languages like Java and C , we have to use this. For example, use this. Without the this. JavaScript restricts the characters that can make a field or a method name.
Recall using special method names like Symbol. Writing a method named Symbol. We had to place it within [], like so: [Symbol. To create a computed property, we place a variable containing the name of the property as the value in []. Alternatively, we can place a string or a template literal within [] as well. In essence, it contains the string "New Year's Day" as its value. Within the constructor of the Holidays class, we use the variable NYD to create a computed field with the contained string as field name.
Instead of using a variable, we may also embed a string or template literal directly within the [], like we do for the field named "Valentine's Day" or the method named 'list holidays'. If that expression appears on the left side of an assignment, the value on the right side of the assignment is assigned to that field.
For example, the string 'July 4' is assigned to the computed field '4th of July' in the previous code. To invoke the method named list holidays, we either place that string, or a variable containing that string, inside [], like methodName, which contains that string as value. The after the [] tells JavaScript to invoke as a method instead of accessing the computed name as a field. Creating Properties JavaScript now supports C -style properties.
From the caller point of view, a property gives an illusion of a field but works as a method. Suppose we want to know how old a car is. The year of make is provided when an instance is created. C developers write properties instead of getter methods, and JavaScript now provides the same capability. A property may have a getter, a setter, or both.
If a property has only a getter, it becomes a read-only property. Ignoring the word get for a moment, the code is no different from writing a method named age. Take it up a notch with features like infinite series, promises, async, and metaprogramming to create flexible, powerful, and extensible libraries.
While the evolved features of the language will draw you in, the hundreds of examples in this book will pin the concepts down, for you to use on your projects. Take command of modern JavaScript and unlock your potential to create powerful applications. To try out the examples in the book you will need a computer with Node. This site comply with DMCA digital copyright. We do not store files not owned by us, or without the permission of the owner.
We also do not have links that lead to sites DMCA copyright infringement. If You feel that this book is belong to you and you want to unpublish it, Please Contact us. Download e-Book. Posted on. Page Count. Venkat Subramaniam,.
0コメント