Working With Function Arguments. Iterators and Symbols. Arrow Functions and Functional Style. Literals and Destructuring. Working with Classes. Using Inheritance. Using Modules. Keeping Your Promises. Exploring Metaprogramming. Deep Dive into Metaprogramming. Join , learners from companies like. Teams of every size choose Educative for Business. Learn in-demand tech skills in half the time. Early Access Courses.
Assessments New. Projects Beta. Free Trial New. For Educators. 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. Placing get in front of the method turns the method name into a property. We have to use the property name directly to refer to it, like so: console. If we place car. Since we do not have a setter for this property, JavaScript will quietly ignore the assignment. If we use 'use strict';—and we should; see Making Objects const, on page 21—then the assignment will result in an error: Cannot set property age of which has only a getter.
The getter for the distanceTraveled property merely returns the value in the this. The setter for the property, however, throws an exception if the value provided is less than the current value in this. Then we access the property distanceTraveled to get the current value of this. Once again we access the property to get its current value of Finally, within the safety net of the try-catch block, we set a value of 1 for the property.
Since this value is less than the current value in this. A property setter is useful to perform some checks and verifications before a field is modified. Defining Class Members When creating abstractions, we often arrive at methods that may not be specific to any particular instance. Sometimes they are general and sometimes they may deal with multiple instances. A class method, instead of an instance method, is used to design these.
It does not, however, provide an elegant way to define static fields. For this, we have to step out of the class definition, like so: Car. Of course, the class property getters and setters will not have implicit access to any instance properties, fields, or methods. The keyword this within static getters, static setters, and static methods is dynamically scoped—it does not refer to the instance of the class.
When a static member is called on a class, this refers to the class, but if this is bound to some other object by the caller, then this may refer to something other than the class. While we may use this to refer to the static members, it is safer to use the class name, like Car. Class Expressions Class expressions are useful to create dynamic classes at runtime based on, for example, properties you read from a file, database, or user-provided input.
JavaScript supports both a class statement—which you use to define a class— and a class expression. Class statements are more common than class expressions, but the latter is useful to create classes dynamically. Within the body of the function, we use a class expression to create and return a class with no explicit name—this feature enables us to create C -like anonymous classes in JavaScript.
Within the anonymous class, we create a constructor, which also takes a rest parameter of values to be assigned to the fields. Since the field names are not known at code writing time, we use the [] notation to access the fields based on their names contained in the fields array. These correspond to the field names we provided in the second call to the createClass function.
In rare situations, you may find it useful to give a name for a class defined using a class expression. Outside, the class is known only by the name to which the expression was assigned—Movie in this example.
If we try to refer to it using the internal name Show, we will run into a runtime exception, as we see in the output: Movie is the class name [Function: Show] creating instance Show is not defined The internal name is useful to call a static method of the class that is defined using class expression from within an instance method or another static method of the class. In other languages, you may have used arrays, lists, sets, associative maps, or dictionaries. Sadly, JavaScript offered only arrays in the past.
When programmers needed a set or a map, they resorted to workarounds. These workarounds made the code hard to maintain, and when the code resulted in unintended behavior, we had more errors to deal with. JavaScript now offers built-in classes for sets and maps as first-class citizens in the language. We will take a look at sets first and then maps. We will wrap up by looking at some special variations of these two classes for better memory use.
Using Set The Array class that has been available in JavaScript from the beginning is sufficient to deal with an ordered collection of data. However, what if you wanted to create an unordered collection? What if you needed values held in the collection to be unique? Say you want to keep a collection of credit cards that belong to a user.
You may want to query whether a particular credit card exists in your collection. Take command of modern JavaScript and unlock your potential to create powerful applications. Errata, typos, suggestions. Releases: P1. Reactive Programming with RxJS 5. Test-Driving JavaScript Applications. Forge Your Future with Open Source. Simplifying JavaScript. Only Please support indie bookstores! Newsletter Sign Up.
0コメント