ホームページ  >  記事  >  ウェブフロントエンド  >  ES6の新機能とオブジェクトの構造化代入について詳しく解説(コード例)

ES6の新機能とオブジェクトの構造化代入について詳しく解説(コード例)

不言
不言転載
2018-10-20 16:04:522344ブラウズ

この記事では、ES6 の新しい機能とオブジェクトの分割割り当てについて詳しく説明します。必要な方は参考にしてください。

ES6 は、リテラル構文の拡張、新しいメソッド、改良されたプロトタイプなどを通じてオブジェクトの使用を強化し、分解を通じてオブジェクトのデータ抽出プロセスを簡素化します。

リテラル構文拡張

ES6 モードでオブジェクトを作成するには、リテラルを使用する方がより簡潔です。オブジェクト プロパティの場合、プロパティの初期値を省略できます。計算されたプロパティ名が使用されます。オブジェクト メソッドの定義では、コロンと関数キーワードが削除されます。例は次のとおりです。

// 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

繰り返し定義されたオブジェクト リテラル プロパティの場合、ES5 厳密モードは 重複プロパティ チェックを実行し、エラーをスローします。 ES6 では、厳密モードか非厳密モードに関係なく、同じ名前の プロパティは最後の値 を取得します。

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

新しいメソッドES5 以降続いている設計目標は、新しいグローバル関数の作成を回避し、object.prototype に新しいメソッドを作成しないことです。

特定のタスクの実装を容易にするために、ES6 ではグローバル Object オブジェクトにいくつかの新しいメソッドが導入されています。

Object.is( )

ES6 では、合同演算子の不正確な計算を補うために Object.is() メソッドが導入されています。

アイデンティティ演算子は比較時にキャスト型をトリガーしません。Object.is() の結果も同様ですが、0 と -0 (JS エンジン内の 2 つの異なるエンティティ) と特殊な値の比較結果が異なります。例に示すように、NaN の値は異なります。

// 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
要約すると、Object.is() はすべての値に対してより厳密な同等性判定を実行します。もちろん、等価演算子 (===) の代わりに Object.is() を使用するかどうかは、これらの特殊なケースがコードに影響を与えるかどうかによって決まります。

Object.assign( )

ES6 は、あるオブジェクトが別のオブジェクトのプロパティとメソッドを受け取る Mixin モードを実装するために Object.assign() を追加します。これは継承ではなく受信されることに注意してください。たとえば、demo1:

// demo4
var friend = {}
Object.assign(friend, person)
friend.sayName() // Jenny
console.log(friend.age) // 18
console.log(Object.getPrototypeOf(friend) === person) // false
でオブジェクトを受信する場合、

Object.assign() の前に、多くの JS ライブラリがミキシング メソッド mixin() をカスタマイズして実装していました。オブジェクトの組み合わせの場合、コードは次のようになります。

function mixin(receiver, supplier) {
  Object.keys(supplier).forEach(function (key) {
    receiver[key] = supplier[key]
  })
  return receiver
}
mixin() メソッドは "= 割り当て操作を使用し、

accessor プロパティ をコピーできないことがわかります。 #Object.assign()アクセサー プロパティもコピーできません。代入操作のみが実行され、アクセサー プロパティは最終的に受信オブジェクトのデータ プロパティに変換されます。例は次のとおりです。 <pre class="brush:php;toolbar:false">// 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' }</pre>

Object.setPrototypeOf( )

通常、プロトタイプはコンストラクターまたは Object.create() を通じて作成されるときに指定されます。 ES6 では、オブジェクトのプロトタイプを変更するための Object.setPrototypeOf() メソッドが追加されています。

たとえば、person オブジェクトを継承するコーダー オブジェクトを作成し、コーダー オブジェクトのプロトタイプを変更します。

// 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

オブジェクト プロトタイプは、内部の独自プロパティ [[Prototype] に格納されます。 ] の場合、Object.getPrototypeOf() を呼び出すと、そこに格納されている値が返され、Object.setPrototypeOf() を呼び出してその値を変更します。この方法は、オブジェクト プロトタイプの操作を強化します。次のセクションでは、プロトタイプを操作する他の方法に焦点を当てます。

強化されたオブジェクト プロトタイプ

プロトタイプは、JS 継承の基礎であり、プロトタイプをより柔軟に使用できるように、プロトタイプに多くの改良が加えられています。プロトタイプを変更するための新しい Object.setPrototypeOf() に加えて、プロトタイプへのアクセスを簡素化するための Super キーワードも導入されました。

Super キーワード

ES6 では、より簡単にアクセスできるように Super が導入されました。前のセクションでは、ES5 が Object.getPrototypeOf() を使用してオブジェクト プロトタイプを返すことができることを紹介しました。例は、Super の利便性を示しています。オブジェクトがプロトタイプ メソッドを再利用し、独自のメソッドを再定義する必要がある場合、2 つの実装メソッドは次のとおりです。

// 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

coder1 オブジェクトの getName メソッドにも call(this) が必要です。プロトタイプメソッドの this は比較的複雑で、多重継承では再帰呼び出しスタックのオーバーフローエラーが発生しますが、Super を直接使用するのは非常に簡単で安全です。

Super は省略メソッドで使用する必要があることに注意してください。そうしないと、エラーが報告されます。たとえば、次のコードの実行時に構文エラーが発生します。

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

この例では、getName が次のようになります。現在のコンテキストでの匿名関数によって定義された属性 スーパー参照を呼び出すことは不正です。理解できない場合は、メソッドの依存オブジェクトを詳しく調べてください。

メソッドの従属オブジェクト

ES6 より前は、「メソッド」はデータではなく関数を持つオブジェクト プロパティでした。ES6 では、メソッドが [[HomeObject]] 内部属性を持つものとして正式に定義されました。関数。

[[HomeObject]] 属性には、現在のメソッドの下位オブジェクトが格納されます。例:

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

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

coder5 オブジェクトのsayName() メソッドの [[HomeObject]] 属性値は次のとおりです。 coder5 では、関数で定義された shareName() はそれをオブジェクトに割り当てないため、その [[HomeObject]] プロパティは定義されていません。これは Super を使用する場合に重要です。

Super は、[[HomeObject]] プロパティで Object.getPrototypeOf() を呼び出してプロトタイプ参照を取得し、次にプロトタイプを検索して同じ名前の関数を取得し、最後にこのバインディングを設定して、対応する方法。

割り当ての構造化

ES6 は、配列とオブジェクト リテラルに新しい機能である構造化を提供します。これにより、データ抽出プロセスが簡素化され、同種のコードが削減されます。構造化の基本的な構文例は次のとおりです。

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 执行环境中的对象
所有标准对象都是内建对象

以上がES6の新機能とオブジェクトの構造化代入について詳しく解説(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。