Home  >  Article  >  Web Front-end  >  Detailed explanation of new functions and destructuring assignment of objects in ES6 (code example)

Detailed explanation of new functions and destructuring assignment of objects in ES6 (code example)

不言
不言forward
2018-10-20 16:04:522343browse

This article brings you a detailed explanation (code example) about the new functions and destructuring assignment of objects in ES6. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. .

ES6 enhances the use of objects through literal syntax expansion, new methods, improved prototypes, etc., and simplifies the data extraction process of objects through deconstruction.

Literal syntax extension

It is more concise to use literals to create objects in ES6 mode. For object properties, the initial value of the property can be abbreviated and can be used. Calculated property name. The definition of object methods eliminates colons and function keywords. The example is as follows:

// Demo1
var value = "name", age = 18
var person = {
  age, // age: age
  ['my' + value]: 'Jenny',  // myname
  sayName () {  // sayName: function()
    console.log(this.myname)
  }
}
console.log(person.age) // 18
console.log(person.myname) // Jenny
person.sayName(); // Jenny

For repeatedly defined object literal properties, ES5 strict mode will perform Duplicate property checks and throw an error , and ES6 has removed this mechanism. Regardless of strict mode or non-strict mode, properties with the same name will take the last value.

// demo2
var person = {
  ['my' + value]: 'Jenny',
  myname: 'Tom',
  myname: 'Lee',
}
console.log(person.myname) // Lee

New methods

A design goal that has been followed since ES5 is to avoid creating new global functions and not creating new methods on object.prototype.
In order to make certain tasks easier to implement, ES6 introduces some new methods on the global Object object.

Object.is( )

ES6 introduces the Object.is() method to compensate for the inaccurate calculation of the congruence operator.

The identity operator will not trigger cast type when comparing, and the results of Object.is() are similar, but for 0 and -0 (two different entities in the JS engine) and special values The comparison results of NaN are different, as shown in the example:

// demo3
console.log(5 == '5') // true
console.log(5 === '5') // false
console.log(Object.is(5, '5')) // false

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

In summary, Object.is() performs a stricter equality judgment on all values. Of course, whether to use Object.is() instead of the equality operator (===) depends on whether these special cases affect your code.

Object.assign( )

ES6 adds Object.assign() to implement Mixin mode, where one object receives the properties and methods of another object. Note that it is received rather than inherited, for example, receiving the object in demo1:

// demo4
var friend = {}
Object.assign(friend, person)
friend.sayName() // Jenny
console.log(friend.age) // 18
console.log(Object.getPrototypeOf(friend) === person) // false

Before Object.assign(), many JS libraries customized the mixing method mixin() to implement object combination , the code is similar to:

function mixin(receiver, supplier) {
  Object.keys(supplier).forEach(function (key) {
    receiver[key] = supplier[key]
  })
  return receiver
}

It can be seen that the mixin() method uses the "=" assignment operation and cannot copy the accessor property. Similarly, Object.assign()The accessor properties cannot be copied either, only the assignment operation is performed, and the accessor properties will eventually be converted into the data properties of the receiving object. Examples are as follows:

// demo5
var animal = {
  name: 'lili',
  get type () {
    return this.name + type
  },
  set type (news) {
    type = news
  }
}
animal.type = 'cat'
console.log(animal.type) // lilicat

var pet = {}
Object.assign(pet, animal)
console.log(animal) // { name: 'lili', type: [Getter/Setter] }
console.log(pet) // { name: 'lili', type: 'lilicat' }

Object.setPrototypeOf( )

Normally, the prototype is specified when created through the constructor or Object.create(). ES6 adds the Object.setPrototypeOf() method to change the prototype of an object.

For example, create a coder object that inherits the person object, and then change the prototype of the coder object:

// demo6
let person = {
  myname: 'Jenny',
  sayName () { 
    console.log(this.myname)
  }
}

// 创建原型为 person 的 coder 对象
let coder = Object.create(person) 
coder.sayName() // Jenny
console.log(Object.getPrototypeOf(coder) === person) // true

let hero = {
  myname: 'lee',
  sayName () {
    console.log(this.myname)
  }
}

// 改变 coder 对象的原型为 hero
Object.setPrototypeOf(coder, hero)
coder.sayName() // lee
console.log(Object.getPrototypeOf(coder) === hero) // true

The object prototype is stored in the internal proprietary property [[Prototype]], call Object.getPrototypeOf( ) returns the value stored in it, and calls Object.setPrototypeOf() to change its value. This method strengthens the operation of object prototypes. The next section focuses on other ways of operating prototypes.

Enhanced Object Prototype

Prototype is the basis of JS inheritance. ES6 has made many improvements to the prototype in order to use the prototype in a more flexible way. In addition to the new Object.setPrototypeOf() to change the prototype, the Super keyword is also introduced to simplify access to the prototype.

Super keyword

ES6 introduces Super to more conveniently access the object prototype. The previous section introduced that ES5 can use Object.getPrototypeOf() to return the object prototype. An example illustrates the convenience of Super. When an object needs to reuse prototype methods and redefine its own methods, the two implementation methods are as follows:

// demo7
let coder1 = {
  getName () {
    console.log("coder1 name: ")
    Object.getPrototypeOf(this).sayName.call(this)
  }
}

// 设置 coder1 对象的原型为 hero(demo6)
Object.setPrototypeOf(coder1, hero)
coder1.getName() // coder1 name: lee

let coder2 = {
  getName () {
    console.log("coder2 name: ")
    super.sayName()
  }
}

Object.setPrototypeOf(coder2, hero)
coder2.getName() // coder2 name: lee

The getName method of the coder1 object also needs call(this) to ensure that it is used The this of the prototype method is relatively complicated, and recursive call stack overflow errors will occur in multiple inheritance, but using Super directly is very simple and safe.

Note that Super must be used in the abbreviation method, otherwise an error will be reported. For example, the following code has a syntax error when running:

let coder4= {
  getName: function () { // getName () 正确
    super.sayName() // SyntaxError: 'super' keyword unexpected here
  }

Because in the example getName becomes an attribute defined by the anonymous function, in the current context It is illegal to call a Super reference. If you don’t understand, you can take a closer look at the dependent objects of the method.

Subordinate objects of methods

Before ES6, "methods" were object properties with functions rather than data. ES6 officially defined methods as having [[HomeObject]] internal Attribute function.

[[HomeObject]] attribute stores the subordinate object of the current method, for example:

let coder5 = {
  sayName () {
    console.log("I have HomeObject")
  }
}

function shareName () {
    console.log("No HomeObject")
}

coder5 The [[HomeObject]] attribute value of the sayName() method of the object is coder5, and the function defined shareName() does not assign it to the object, so its [[HomeObject]] property is not defined, which is important when using Super.

Super is to call Object.getPrototypeOf() on the [[HomeObject]] property to obtain the prototype reference, then search the prototype to get the function with the same name, and finally set this binding to call the corresponding method.

Destructuring assignment

ES6 provides a new feature for arrays and object literals - destructuring, which can simplify the data extraction process and reduce homogeneous code. A basic syntax example for destructuring is as follows:

let user = {
  name: 'jenny',
  id: 18
}
let {name, id} = user
console.log(name, id) // jenny 18

注意在这段代码中,user.name 存储在与对象属性名同名的 name 变量中。

默认值

如果解构时变量名称与对象属性名不同,即在对象中不存在,那么这个变量会默认为undefined:

let user = {
  name: 'jenny',
  id: 18
}
let {name, id, job} = user
console.log(name, id, job) // jenny 18 undefined

非同名变量赋值

非同名变量的默认值为undefined,但更多时候是需要为其赋值的,并且会将对象属性值赋值给非同名变量。ES6 为此提供了扩展语法,与对象字面量属性初始化程序很像:

let user = {
  name: 'jenny',
  id: 18
}
let {name, id = 16, job = 'engineer'} = user
console.log(name, id, job) // jenny 18 engineer

let {name: localName, id: localId} = user
console.log(localName, localId) // jenny 18

let {name: otherName = 'lee', job: otherJob = 'teacher'} = user
console.log(otherName, otherJob) // jenny teacher

可以看出这种语法实际与对象字面量相反,赋值名在冒号左,变量名在右,并且解构赋值时,只是更新了默认值,不能覆盖对象原有的属性值。

嵌套解构

解构嵌套对象的语法仍然类似对象字面量,使用花括号继续查找下层结构:

let user = {
  name: 'jenny',
  id: 18,
  desc: {
    pos: {
      lng: 111,
      lat: 333
    }
  }
}

let {desc: {pos}} = user
console.log(pos) // { lng: 111, lat: 333 }

let {desc: {pos: {lng}}} = user
console.log(lng) // 111

let {desc: {pos: {lng: longitude}}} = user
console.log(longitude) // 111

对象类别

ES6 规范定义了对象的类别,特别是针对浏览器这样的执行环境。

普通(Ordinary)对象
具有 JS 对象所有的默认内部行为

特异(Exotic)对象
具有某些与默认行为不符的内部行为

标准(Standard)对象
ES6 规范中定义的对象
可以是普通对象或特异对象,例如 Date、Array 等

内建对象
脚本开始执行时存在于 JS 执行环境中的对象
所有标准对象都是内建对象

The above is the detailed content of Detailed explanation of new functions and destructuring assignment of objects in ES6 (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete