属性記述子はES5に追加された新しい概念であり、その機能はオブジェクトのプロパティにさらに制御を追加することです。
object.defineProperty
属性記述子を研究するには、まずobject.definePropertyメソッドについて話す必要があります。この方法の目的は、オブジェクトの新しいプロパティを定義するか、既存のプロパティを変更することです。プロトタイプは次のとおりです。
コードコピーは次のとおりです。
object.defineProperty(obj、prop、descriptor)
使用例:
コードコピーは次のとおりです。
var obj = {};
object.defineProperty(obj、 'attr'、{value:1});
上記のコードは、objオブジェクトにattributeという名前の属性を追加し、値は1です。次の値に相当します。
コードコピーは次のとおりです。
var obj = {};
obj.attr = 1;
それに比べて、object.definePropertyの書き込みはより複雑であるようです。ただし、その最大の秘密は3番目のパラメーターにあります。
データ記述子
Attrを読み取り専用属性にしたいと仮定すると、Writableデータ記述子を追加できます。
コードコピーは次のとおりです。
var obj = {};
object.defineProperty(obj、 'attr'、{
値:1、
書き込み:偽
});
console.log(obj.attr);
obj.attr = 2; // 失敗
console.log(obj.attr);
上記のプログラムを実行すると、2回印刷されたattrの値が1であることがわかります。つまり、属性の書き込みが失敗しました。ただし、割り当て声明の実行には例外がないため、この結果は少し不可解になりますが、失敗します。このような問題がBlockBusterコードで発生した場合、それをトラブルシューティングすることが難しいと想像してください。実際、コードが厳密なモードで実行されている限り、例外が生成されます。
コードコピーは次のとおりです。
「Strictを使用」; // strictモードを入力します
var obj = {};
object.defineProperty(obj、 'attr'、{
値:1、
書き込み:偽
});
obj.attr = 2; //例外をスローします
属性を列挙できるかどうかを制御できる別のデータ記述子列挙性を見てみましょう。単にプロパティを定義する場合、このプロパティは、forで列挙できます。
コードコピーは次のとおりです。
var obj = {};
obj.attr = 1;
for(bar i in obj){console.log(obj [i]); }
列挙可能はそれを「隠す」ことができます:
var obj = {};
object.defineProperty(obj、 'attr'、{
値:1、
列挙可能:false
});
for(bar i in obj){console.log(obj [i]); }
上記のコードを実行すると、この時点で属性を列挙できないため、コンソールには何も出力されません。
そうは言っても、質問があるかもしれません:属性記述子を変更できますか?たとえば、読み取り専用のプロパティを再び書くことができると定義できますか?実際、これは別のデータ記述子構成に依存します。これにより、属性記述子を変更できるかどうかを制御できます。
コードコピーは次のとおりです。
var obj = {};
object.defineProperty(obj、 'attr'、{
値:1、
手紙:false、
設定可能:true
});
object.defineProperty(obj、 'attr'、{
手紙:本当
});
obj.attr = 2;
上記のコードは、最初にattrを読み取り専用属性として定義し、次に書き込み可能なものとして再定義します。したがって、タートへのライティングは成功しています。
アクセス記述子
アクセス記述子は、オブジェクト指向のGet/Set Accessorに似ています。
コードコピーは次のとおりです。
var obj = {};
object.defineProperty(obj、 'attr'、{
set:function(val){this._attr = math.max(0、val); }、
get:function(){return this._attr; }
});
obj.attr = -1;
console.log(obj.attr); // 0
上記のコードでは、ATTRへのアクセスが実際に_ATTRへのアクセスになり、最小値は設定関数の0に制限されます。
属性記述子を取得します
上記のすべてはすべて設定属性記述子ですので、設定記述子を取得するにはどうすればよいですか? object.getownPropertyDescriptorはこれを行うことができます。
コードコピーは次のとおりです。
var obj = {};
object.defineProperty(obj、 'attr'、{
値:1、
手紙:false、
設定可能:true
});
var desc = object.getownPropertyDescriptor(obj、 'attr');
console.dir(desc);
オブジェクトコントロール
前述のobject.definePropertyは、オブジェクトのプロパティで動作しますが、以下の3つの方法はオブジェクトで直接動作します。
object.preventextensionsは、オブジェクトが新しいプロパティを持つことを防ぐことができます。
コードコピーは次のとおりです。
var obj = {};
obj.attr = 1;
object.preventextensions(obj);
obj.attr2 = 2; //失敗
Object.Sealは、オブジェクトのみを変更するためにオブジェクトのみを作成できます(プロパティが読み取り専用である場合、プロパティ値を変更できません):
コードコピーは次のとおりです。
var obj = {};
obj.attr = 1;
object.seal(obj);
obj.attr = 1.5;
obj.attrを削除します。 // 失敗
Object.Freezeは、オブジェクトを完全に変更していないことができます。
コードコピーは次のとおりです。
var obj = {};
obj.attr = 1;
object.freeze(obj);
obj.attr = 1.5; // 失敗
obj.attr2 = 2; //失敗
その後、再び尋ねることができます、オブジェクトがexedextensionsを防止したかどうか、シールまたはフリーズしたかどうかをどのようにして知ることができますか?答えは、それぞれobject.isextensible、object.issaled、およびobject.isprozenを呼び出すことです。これらの3つの機能の使用は比較的単純で、もはや面倒ではありません。
一般に、オブジェクトは属性記述子を介してさらに厳密に制御でき、プログラムロジックの厳密さが強化されます。唯一の欠点は、ES5が基本的にIE9で実装されていることです(IE9はまだ厳密なモードをサポートしていません)。国内のIE8共有がまだ比較的高いことを考慮すると、この一連のことはモバイルブラウザーとnode.jsでのみ使用できます。