序文
ではJavaScript
、ほとんどすべての値が特定のタイプのオブジェクトです。Es6
また、Es6
オブジェクトの機能を改善し、さまざまな方法でオブジェクトの使用を強化し、単純な文法拡張を通じてオブジェクトを操作し、オブジェクトと対話するためのより多くのメソッドを提供することに焦点を当てています。以下に紹介しましょう。
オブジェクトリテラル構文拡張
オブジェクトリテラルで十分です。つまり、オブジェクトを作成する必要があり、冗長なコードを記述する必要はありません。簡潔な構文で直接実現できます。次に、Es6がオブジェクト用に作成した機能を見てください。
属性の初期値の省略形
Es5では、オブジェクトリテラルは単なるキーとコレクションです。つまり、初期化プロパティにいくつかの繰り返しがあります。
function person(name) {
return {
name: name
}
}
Es6では、name
attributeの省略形でこの属性を省略できます。オブジェクトの属性と変数の名前が同じ場合は、コロンと値を省略できます。次のケースを見てください
function person(name) {
return {
name
}
}
オブジェクトメソッドの省略構文
Es6は、オブジェクトリテラルのオブジェクト省略メソッドも改善しました。Es5では、オブジェクトメソッドを定義するときにフルネームを記述する必要があります。
Es5ケース
let person = {
test: function() {
}
}
Es6ケース
let person() {
test() {
}
}
Es6オブジェクトのメソッド省略形により、匿名式が定義されます。この関数は、Es5とまったく同じ特性を備えています。Es5で定義されたオブジェクト関数とEs6の省略関数定義の唯一の違いは、省略関数を使用できることsuper
です。
計算可能な属性名
Es5では、計算によって属性名を取得する場合は、[]
代わりに角かっこを使用する必要があります。
let person = {
}
let value = "hello WaRen"
person["wa ren"] = "蛙人"
person[value] = "value"
上記の例では、es5で行ったことです。オブジェクトのキー値が変数の場合、オブジェクトの角かっこを使用して追加します。
Es6では、オブジェクトリテラルで計算可能な属性の名前を使用できます。次の例を見てみましょう。
let key = "name"
let person = {
[key]: "蛙人" // 在对象字面量中这样使用[]方括号定义key是Es6语法
[`${
key}_test`]: "test"
}
上記のオブジェクトリテラルで使用されている角括弧は、属性名を計算でき、式を記述できることを示しています。その後、最終的なキー値が文字列タイプとして返されます。覚えておいてください在对象字面量中使用方括号[]定义key值是Es6中的语法
。私はまた知っています(基盤はしっかりしていません)、Es6をEs5に変換するために聖書をテストした後、あなたは結果を見ることができます。
重複するオブジェクトリテラル属性
Es5 strictモードでは、オブジェクトリテラルの繰り返し属性の検証が追加され、同じ名前の属性が同時に複数ある場合は例外がスローされます。次の例を見てください
"use strict"
var person = {
name: "蛙人",
name: "张三" // 在Es5严格模式下会抛出语法错误
}
Es5 strictモードでは、2番目の属性name
によって構文エラーがトリガーされますが、Es6での重複属性チェックは削除されています。Es6では、strictモードであるかどうかに関係なく、コードは属性を繰り返しません。検証、繰り返される属性の場合、後者は前者をカバーします。ps:私は未熟な涙を流したことを知りました。。。
"use strict"
let person = {
name: "蛙人",
name: "张三"
}
上記の例では、これがEs6標準の繰り返し属性であり、例外はスローされませんが、backオブジェクトが前のオブジェクトを上書きし、最後のname
属性が「Zhang San」であることがわかります。これで、ブラウザーはEs6標準を実行しています。
Es6オブジェクトの新しいメソッド
Es6Object
は、グローバルオブジェクトにいくつかの新しいメソッドを導入しました。
Object.is
Es5にいるときは、値を比較するために==
等式演算子または===
合同演算子を使用することがよくありますが、Es5では、等式演算子または合同演算子は完全に正確ではありません。+0和-0
これは公式Webサイトの例です。これはJavaScript
エンジン内にあります。2つの異なるエンティティが表され、合同演算子または等式演算子を使用するとture
、が返され、NaN == NaN
falseも返されます。ただし、Es6には、Object.is
これらの欠点を補うためのObject.is
メソッドがあります。このメソッドは2つのパラメーターを受け取ります。2つのパラメーターの値が等しく、タイプも等しい場合は、次のようになります。true
console.log(+0 == -0) // ture
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
console.log(10 == "10") // true
console.log(10 === "10") // false
console.log(Object.is(10, "10")) // false
上記の例では、Object.is
メソッドが非常に厳密であることがわかりますが、これは特別な場合にのみ使用されるため、==
またはを放棄する必要はありません===
。
Object.assign
Object.assignメソッドは、任意の数のソースオブジェクトを受け取ることができます。最初のパラメーターはレシーバーであり、これが最終的な戻り値です。2番目のパラメーターは後で最初のパラメーターにコピーされるため、属性key
値を持つ複数のソースオブジェクトがある場合同じ名前の場合、後ろのオブジェクトが前のオブジェクトを上書きします。次の例を見てください
let test1 = {
name: "蛙人"
}
let test2 = {
name: "张三"
}
let result = Object.assign({
}, test1, test2)
console.log(result) // {name: "张三"}
上記の例では、上記のオブジェクト属性が同じ名前の場合、後者が前者を上書きすることがわかります。渡されたパラメータが非オブジェクトの場合、実行できますが、無視されます。次の例を見てください
let result = Object.assign({
}, 1, 2, 3)
console.log(result) // {}
注:Object.assignメソッドは、値関数(アクセサー属性)をオブジェクトにコピーできません。Object.assignメソッドは割り当て操作を実行するため、オブジェクトは最終的に通常の属性に変換されます。
let test = {
get name() {
return "蛙人"
}
}
let result = Object.assign({
}, test)
console.log(Object.getOwnPropertyDescriptor(result, "name")) // {configurable: true enumerable: true value: "蛙人" writable: true}
上記の例では、オブジェクトのコピーの最終結果を確認できます。値関数は実際に失われてい对象的描述属性
ます。取得に応じて確認できます。わからない場合は对象的描述属性
、私の記事「JavaScriptオブジェクトの詳細な理解」を読むことができます。
Object.setPrototypeOf
Es5にObject.getPrototypeOf
は、オブジェクトのプロトタイプを取得する方法がありますが、Es5には、オブジェクトのプロトタイプを設定する方法がありません。オブジェクトのプロトタイプを設定する場合はxx.__proto__ = xx.__proto__
、このように記述しても問題ありません。しかし、それは無理です。したがって、Es6はObject.setPrototypeOf
メソッドを提供します。このメソッドは、2つのパラメーターを受け入れます。最初のパラメーターは変更されたオブジェクトであり、2番目のパラメーターはプロトタイプオブジェクトです。次の例を見てください
let person = {
}
function Fn() {
}
let fn = new Fn()
Object.setPrototypeOf(person, fn)
console.log(person)
上記の例でperson
は、プロトタイプオブジェクトがプロトタイプオブジェクトに変更されてfn
いることperson
がわかります。このとき、オブジェクトにアクセスすると、プロトタイプオブジェクトが変更されていることがはっきりとわかります。
Object.values
Object.values
メソッドは配列を返します。メンバーはパラメータオブジェクト自体であり、継承とプロトタイプは含まれていません。
let person = {
name: "蛙人",
age: 24,
sex: "male"
}
console.log(Object.values(person)) // ["蛙人", 24, "male"]
Object.entries
Object.entries
このメソッドは配列(つまり、2次元配列)を返します。メンバーはパラメーターオブジェクト自体であり、属性のキーと値のペアの配列であり、継承とプロトタイプは含まれていません。
let person = {
name: "蛙人",
age: 24,
sex: "male"
}
console.log(Object.entries(person)) // [["name", "蛙人"], ["age", 24], ["sex", "male"]]
Object.fromEntries
Object.fromEntries
はいObject.entries
、逆の操作です。戻り値はオブジェクトであり、キーと値のペアの配列をオブジェクトに変換するために使用されます。
let testArr = [
["name", "蛙人"],
["age", 24],
["sex", "male"]
]
console.log(Object.fromEntries(testArr)) // {name: "蛙人", age: 24, sex: "male"}
独自のオブジェクトプロパティの列挙順序
オブジェクト属性の列挙順序は、jsエンジンの製造元によって決定されるEs5では定義されていません。ただし、Es6は、オブジェクト自体のプロパティが列挙されて返される順序を指定します。自己所有属性の列挙順序の基本的なルールは次のとおりです。
- すべての数字キーは昇順で並べ替えられます
- すべての文字列キーは、追加された順序で並べ替えられます
- すべてのシンボルキーは、追加された順序で並べ替えられます
let o = {
4: 4,
1: 1,
b: "b",
a: "a"
}
o.c = "c"
console.log(Object.keys(o)) // ["1", "4", "b", "a", "c"]
console.log(Object.getOwnPropertyNames(o)) // ["1", "4", "b", "a", "c"]
for (let i in o) {
console.log(i) // 1 4 b a c
}
上記の例では、オブジェクト列挙プロパティはすべてEs6のルール順序に従って返されますが请注意 ,对于数字键,尽管在对象字面量中顺序是随意的
、列挙中に再結合およびソートされることがわかります。文字列は数字キーの直後に続き、オブジェクト内の属性の順序で返され、最後に文字列キーの値が動的に追加されます。
プロトタイプアクセスを簡素化するためのスーパーリファレンス
Es6では、super
キーワードが新たに提供されています。この方法は、現在のプロトタイプのオブジェクトを取得するための使用を簡素化するためのものです。次の例を見てください
Es5ケース
let person = {
getName() {
return Object.getPrototypeOf(this).getVal.call(this)
}
}
let o = {
getVal() {
return "蛙人"
}
}
Object.setPrototypeOf(person, o)
console.log(person.getName()) // 蛙人
上記の例では、最初にperson
プロトタイプをo
オブジェクトに設定し、次にperson
オブジェクトを呼び出すと、このgetName
メソッドで現在のプロトタイプが取得され、プロトタイプのメソッドが呼び出されることがわかります。これは、o
オブジェクトと呼ばれます。
Es6ケース
let person = {
getName() {
return super.getVal.call(this)
}
}
let o = {
getVal() {
return "蛙人"
}
}
Object.setPrototypeOf(person, o)
console.log(person.getName()) // 蛙人
上記の例では、上記のコードをわずかに調整し、キーワードにObject.getPrototypeOf
置き換えたことがわかりますsuper
。super
キーワードの役割は、Object.getPrototypeOf
メソッドではなくオブジェクトのプロトタイプにアクセスすることです。ただし、super
キーワードには、オブジェクトリテラルの省略形のメソッドでしか使用できないという欠点もあります。次のケースを見てください
let person = {
getName: function() {
return super.toString() // 报错
}
}
上記の例では、属性はperson
オブジェクト内で匿名でfunction
定義されています。現在のコンテキストでsuper
参照することは違法であるため、エラーがスローされます。では、なぜ同じ機能であるが異なるのか、それから私たちは見下し続けます。
区別する正しい方法の定義
方法
この概念は、Es6以前には規定されていませんでした。メソッドは、オブジェクトではなく関数を持つプロパティのみです。Es6では、メソッドは[[HomeObject]]
、メソッドが属するオブジェクトに対応する内部プロパティを持つ関数として正式に定義されています。次の例を見てください
let person = {
getName() {
} // 是方法
}
function getName() {
} // 不是方法
上記の例では、person
オブジェクトが定義されており、getName
メソッドがあります。関数はperson
オブジェクトに直接割り当てられているため、getName
メソッドの[[HomeObject]]
属性値はperson
オブジェクトです。次にfunction
、以下のキーワードで定義されたgetName
メソッドを見てください。現時点では、オブジェクトに割り当てられていないため、[[HomeObject]]
プロパティは明確に定義されていません。super
キーワードを使用しない場合、これら2つの機能のわずかな違いは大きな問題ではありません。ただしsuper
、キーワードを使用することは特に重要です。
super
キーワード参照は、[[HomeObject]]
属性を介して後続の実行プロセスを決定するために使用されるためです。super
キーワードは、最初に[[HomeObject]]
プロパティで現在のオブジェクト(プロパティ値)を検索します。つまりperson
、呼び出し元のObject.getPrototypeOf
メソッドで現在のプロトタイプを取得し、次にプロトタイプで同じ名前の現在の関数を検索し、最後にthis
バインディングを設定して呼び出します。 。これが、上記のsuper
キーワードがエラーを報告する理由です。