Extended object functionality

ES6 focuses on improving the utility of objects because almost all values in JS are objects of some type.

Object classes

JS uses mixed terms to describe objects found in the standard, rather than those added by a runtime environment (such as a browser or Node.js), and the ES6 specification explicitly defines each category of objects.

Object categories include:

  • Normal objects: have all the default internal behavior of JS objects.
  • Exotic objects: Their internal behavior differs from the default behavior in some ways.
  • Standard object: inES6Object defined in, for exampleArray,DateAnd so on. Standard objects can be ordinary or exotic.
  • Built-in objects: objects provided by the JS runtime environment when the script starts running. All standard objects are built-in objects.

Extension of object literal syntax

Object literals. Object literals are simple collections of key/value pairs enclosed in curly braces. As follows:

    const person = {
        name: 'zzzhim'.age: 22.sex: 'male'
    }
Copy the code

? Object literals are one of the most popular patterns in JS (JSON is based on this syntax), and they exist in almost every JS file on the Internet.

Shorthand for property initializers

Object literals are simple collections of key/value pairs. This means that there may be some duplication when the property values are initialized. As follows:

    function createObject(name, age, sex) {
        return {
            name: name,
            age: age,
            sex: sex
        }
    }
Copy the code

The createObject() function creates an object with the same attribute and parameter names. This result is actually somewhat repetitive, although there are keys on one side and values on the other.

ES6 gives us a much easier way to write. As follows:

    function createObject(name, age, sex) {
        return {
            name,
            age,
            sex
        }
    }
Copy the code

In the above code we can use the shorthand of an attribute initializer to eliminate duplication of object names and local variables. We can omit values and colons when properties and names in objects are duplicated.

? This is because when an object literal has only a name, the JS engine looks for a variable with the same name in the current scope and its surrounding scope, and if it finds a variable with the same name, it assigns its value to the property of the object with the same name.

Methods shorthand

ES6 also improves the syntax for assigning values to object literal methods. In ES5 and earlier, you had to specify a name and add methods to an object with a full function definition. As follows:

    const person = {
        name: 'zzzhim'.sayName: function() {
            console.log(this.name)
        }
    }
Copy the code

In ES6 we can make this syntax more concise by omitting the/colon and function/ keyword.

    const person = {
        name: 'zzzhim',
        sayName() {
            console.log(this.name)
        }
    }
Copy the code

This shorthand syntax is also known as Concise Method syntax.

? > The only difference is that method abbreviations can use super, while non-abbreviations cannot. (Super will be used later).

Attribute names need to be computed

In ES6, the evaluated attribute name is part of the literal syntax of the object, which is expressed in square brackets. As follows:

    const lastName = "last name"
    const person = {
        "first name": "zzz",
        [lastName]: "him"
    }

    console.log(person["first name"]) // zzz
    console.log(person[lastName])     // him
Copy the code

We can also use expressions in square brackets. As follows:

    const lastName = "last"
    const person = {
        "first name": "zzz",
        [lastName + " name"] :"him"
    }

    console.log(person["first name"]) // zzz
    console.log(person["last name"])     // him
Copy the code

? Using the square brackets notation, anything that can be placed inside the square brackets of an object instance can be used in the object literal as the name of the property to be evaluated.

The new method

ES6 introduces two new methods on Object objects, object.is () and object.assign ().

Object.is()methods

When comparing two values in JS, we often use the equality operator (==) or the strict equality operator (===).

When we use the equality operator, the equality operator compares two values for equality and implicitly converts the values to the same type before the comparison.

    const num = 0
    const str = "0"

    console.log(num == num) // true
    console.log(num == str) // true
    console.log(str == str) // true
    console.log(num == false) // true
    console.log(num == null) // false
    console.log(str == null) // false
    console.log(num == undefined) // false
    console.log(str == undefined) // false
    console.log(null= =undefined) // true
Copy the code

When we use the strict equality operator. The strict equality operator compares whether two values are equal and whether the types are equal. The result is true when both values and types are equal. There is no implicit conversion between two values being compared before they are compared.

    const num = 0;
    const obj = new String("0");
    const str = "0";
    const b = false;

    console.log(num === num); // true
    console.log(obj === obj); // true
    console.log(str === str); // true

    console.log(num === obj); // false
    console.log(num === str); // false
    console.log(obj === str); // false
    console.log(null= = =undefined); // false
    console.log(obj === null); // false
    console.log(obj === undefined); // false
Copy the code

But the strict equality operator is not entirely accurate, for example, it will consider +0 and -0 equal, even though the two are represented differently in the JS engine; Also, NaN === NaN returns false, so it is necessary to use the isNaN() function to properly detect NaN.

ES6 introduced the object.is () method to compensate for the remaining oddity of the strict equality operator. This method takes two arguments and returns true if their values are equal.

    console.log(+0= =0)            // true
    console.log(+0= = =0)           // true
    console.log(Object.is(+0.0))   // false

    console.log(NaN= =NaN)          // false
    console.log(NaN= = =NaN)         // false
    console.log(Object.is(NaN.NaN)) // true
Copy the code

? The result of object.is () is the same as the strict equality operator in many cases, except that +0 is not equal to -0 and NaN is equal to NaN.

Object. The assign () method

The object.assign () method is used to copy the values of all enumerable properties from one or more source objects to target objects. It will return the target object.

The object.assign () method copies only the enumerable properties of the source Object itself to the target Object. If an attribute in the target object has the same key, the attribute is overwritten by an attribute in the source object. Properties of subsequent source objects similarly override properties of previous source objects.

    const target = {
        a: 1.b: 2
    }

    const source = {
        b: 3.c: 4
    }

    const copy = Object.assign(target, source)
    console.log(copy)
Copy the code

Note that object.assign () makes a shallow copy of the attribute value. If the value of the source object is a reference to an object, then it only refers to that reference. As follows:

    const target = {
        a: 1.b: 2
    }

    const source = {
        b: 3.c: {
            a: 1}}const copy = Object.assign(target, source)
    console.log(copy)   // { a: 1, b: 3, c: { a: 1 } }

    source.c.a = 2

    console.log(source) // { a: 1, b: 3, c: { a: 2 } }
    console.log(copy)   // { a: 1, b: 3, c: { a: 2 } }
Copy the code

? > If we need to do deep copy, we can use JSON to do deep copy, which is a very common way to do deep copy nowadays.

Modify the prototype of the object

Typically, the prototype of an Object is specified when the Object is created through the constructor or the object.create () method. ES6 allows us to modify the prototype of any Object by adding the object.setProtoTypeof () method.

Object.setprototypeof () takes two arguments: the first argument is the Object to which the prototype is to be set, and the second argument is the new prototype of that Object (Object or NULL).

    const person = {
        getGreeting() {
            return "Hello"}}const dog = {
        getGreeting() {
            return "Woof"}}const friend = Object.create(person)

    console.log(friend.getGreeting()) // Hello
    console.log(Object.getPrototypeOf(friend) === person) // true

    Object.setPrototypeOf(friend, dog)

    console.log(friend.getGreeting()) // Woof
    console.log(Object.getPrototypeOf(friend) === person) // false
    console.log(Object.getPrototypeOf(friend) === dog) // true
Copy the code

From the above example we can see that object.getProtoTypeof () can be used to point the prototype of one Object to another.

? > The actual value of the Object Prototype is stored in an internal attribute [[Prototype]], which is returned by the object.getProtoTypeof () method and modified by the Object.setProtoTypeof () method. However, there are more ways to use the [[Prototype]] attribute.

Simple prototype access using super references

The super keyword is used to access and call functions on the parent object of an object. Super is a pointer to the prototype of the current Object, which is essentially the value of Object.getProtoTypeof ().

    const obj1 = {
        method() {
            console.log("obj1")}}const obj2 = {
        method() {
            Object.getPrototypeOf(this).method()
        }
    }

    Object.setPrototypeOf(obj2, obj1)
    obj2.method() // obj1

    const obj3 = {
        method() {
            console.log("obj3")}}Object.setPrototypeOf(obj2, obj3)
    obj2.method() // obj3
Copy the code

Formal method definitions

Before ES6, the concept of “method” had never been formally defined and previously referred only to functional properties of objects (not data properties). ES6 formally defines a method as a function with an internal property of [[HomeObject]] that points to the object to which the method belongs.

    const person = {
        / / method
        getGreeting() {
            return "Hello"}}// Not a method
    function shareGreeting() {
        return "Hi!"
    }
Copy the code

This example defines a Person object with a single getGreeting() method. Since getGreeting() is assigned directly to an object, its [[HomeObject]] property value is Person. The shareGreeting() function, on the other hand, is not assigned the [[HomeObject]] property because it is not assigned to an object when it is created. In most cases, this difference doesn’t matter, but using a super reference is a different story.

Any reference to super uses the [[HomeObject]] property to determine what to do. The first step is to call Object.getProtoTypeof () on [[HomeObject]] to get a reference to the prototype; Next, look for the function with the same name on the prototype; Finally, create the this binding and call the method.

conclusion

Object is central to JS programming, and ES6 has made some useful improvements to it, making it easier to use and more powerful.

ES6 makes several improvements to object literals. Shorthand attribute definitions make it easier to assign scoped variables to properties of the same name; Computable property names allow you to specify non-literal values as property names, as it has been used elsewhere; Method shorthand lets you define methods in object literals by omitting the colon and function keyword, thereby reducing the number of characters entered. ES6 also eliminates checking for duplicate property names in object literals, meaning you can write two properties with the same name in an object literal without throwing an error.

The object.assign () method makes it easier to change multiple attributes of a single Object at once, which is useful when you use mixins. The object.is () method performs strict equality comparisons on any value and effectively becomes a safer alternative to === when dealing with special JS values.

The enumeration order of the object’s own properties is explicitly defined in ES6. When enumerating properties, numeric keys always appear first and are sorted in ascending order, followed by string keys, followed by symbol keys, each in added order, respectively.

Thanks to ES6’s object.setProtoTypeof () method, it is now possible to change the prototype of an Object after it has been created.

Finally, you can use the super keyword to call a method on the object’s prototype, and the called method is set with its internal this binding to automatically work with that value.

6 Reading notes.

  1. ES6 block-level binding, let, const declaration
  2. Strings and Regular expressions (RegExp)
  3. Functions
  4. Extended object functionality
  5. Deconstruction assignment
  6. Symbol and Symbol attribute

Refer to the article

  • MDN
  • Understanding ECMAScript 6
  • Understanding ECMAScript 6

githubaddress