提起される最後の2つの問題-
Proxy
      
      と
Symbol
      
      はECMAScript 6仕様に関連しており、一部の近代的なブラウザでのみ部分的に実装および実装されています。
ゲッターとセッター
ゲッターとセッターはしばらくの間JavaScriptで使用できましたが、頻繁に使用する必要があることに気づきませんでした。 多くの場合、次のようなプロパティを取得するための通常の関数を作成します。
 /** * @param {string} prefix * @constructor */ function Product(prefix) { /** * @private * @type {string} */ this.prefix_ = prefix; /** * @private * @type {string} */ this.type_ = ""; } /** * @param {string} newType */ Product.prototype.setType = function (newType) { this.type_ = newType; }; /** * @return {string} */ Product.prototype.type = function () { return this.prefix_ + ": " + this.type_; } var product = new Product("fruit"); product.setType("apple"); console.log(product.type()); //logs fruit: apple
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
ゲッターを使用すると、このコードを簡素化できます。
 /** * @param {string} prefix * @constructor */ function Product(prefix) { /** * @private * @type {number} */ this.prefix_ = prefix; /** * @private * @type {string} */ this.type_ = ""; } /** * @param {string} newType */ Product.prototype = { /** * @return {string} */ get type () { return this.prefix_ + ": " + this.type_; }, /** * @param {string} */ set type (newType) { this.type_ = newType; } }; var product = new Product("fruit"); product.type = "apple"; console.log(product.type); //logs "fruit: apple" console.log(product.type = "orange"); //logs "orange" console.log(product.type); //logs "fruit: orange"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
コードは少し冗長であり、構文は少し変わっていますが、
get
      
      と
set
      
      を使用する利点は、直接使用するとより明らかになります。 私は自分自身にそれを見つけました:
 product.type = "apple"; console.log(product.type);
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      よりはるかに読みやすい:
 product.setType("apple"); console.log(product.type());
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      ただし、組み込みの不正なJavaScriptアラームは、オブジェクトインスタンスへの直接アクセスとプロパティの設定を確認するとトリガーされます。 長い間、クラスインスタンスへのプロパティのby意的な割り当てを避けるために、バグと技術的要件によって教えられました。これは、情報がそれらの間で確実に分散されるという事実につながるためです。 また、設定値が返される順序には微妙な違いがあります。以下の例を参照してください。
 console.log(product.type = "orange"); //logs "orange" console.log(product.type); //logs "fruit: orange"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      最初に
“orange”
      
      がコンソールに表示され、次に
“fruit: orange”
      
      が表示されることに注意してください。 設定値が返される間、ゲッターは実行されません。そのため、この形式の省略された書き込みでは、問題が発生する場合があります。
set
      
      返される値は無視されます。
return this.type;
      
      追加
return this.type;
      
      set
      
      すると、この問題は解決しません。 これは通常、セットポイントを再利用することで解決されますが、ゲッターを持つプロパティの問題が発生する可能性があります。
defineProperty
構文
get propertyname ()
      
      はオブジェクトリテラルで機能し、前の例では
Product.prototype
      
      オブジェクト
Product.prototype
      
      を割り当てました。 これには何の問題もありませんが、このようなリテラルを使用すると、プロトタイプ呼び出しの連鎖が複雑になり、継承が実装されます。 リテラルを使用せずにプロトタイプでゲッターとセッターを定義することは可能
defineProperty
      
      を使用して
 /** * @param {string} prefix * @constructor */ function Product(prefix) { /** * @private * @type {number} */ this.prefix_ = prefix; /** * @private * @type {string} */ this.type_ = ""; } /** * @param {string} newType */ Object.defineProperty(Product.prototype, "type", { /** * @return {string} */ get: function () { return this.prefix_ + ": " + this.type_; }, /** * @param {string} */ set: function (newType) { this.type_ = newType; } });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
このコードの動作は、前の例と同じです。 ゲッターとセッターを追加する代わりに、
defineProperty
      
      が
defineProperty
      
      ます。
defineProperty
      
      の3番目の引数はハンドルであり、
set
      
      および
get
      
      に加えて
get
      
      アクセシビリティを構成し、値を設定する機能を提供します。
defineProperty
      
      を使用すると、定数のようなものを作成できます-削除またはオーバーライドされないプロパティ。
 var obj = { foo: "bar", }; //A normal object property console.log(obj.foo); //logs "bar" obj.foo = "foobar"; console.log(obj.foo); //logs "foobar" delete obj.foo; console.log(obj.foo); //logs undefined Object.defineProperty(obj, "foo", { value: "bar", }); console.log(obj.foo); //logs "bar", we were able to modify foo obj.foo = "foobar"; console.log(obj.foo); //logs "bar", write failed silently delete obj.foo; console.log(obj.foo); //logs bar, delete failed silently
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
結果:
 bar foobar undefined bar bar bar
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      foo.bar
      
      このデフォルトの動作は変更を禁止することであるため、例の
foo.bar
      
      をオーバーライドする最後の2つの試行は失敗しました(エラーメッセージによって中断されなかった場合でも)。 この動作を変更するには、
configurable
      
      writable
      
      および
writable
      
      使用でき
writable
      
      。 strictモードを使用すると、一般的なJavaScriptエラーであるため、エラーがスローされます。
 var obj = {}; Object.defineProperty(obj, "foo", { value: "bar", configurable: true, writable: true, }); console.log(obj.foo); //logs "bar" obj.foo = "foobar"; console.log(obj.foo); //logs "foobar" delete obj.foo; console.log(obj.foo); //logs undefined
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
configurable
      
      なキーは、プロパティがオブジェクトから削除されるのを防ぎます。 さらに、
defineProperty
      
      別の呼び出しによるプロパティへの後続の変更を防ぐことができます。
writable
      
      キーを使用すると、プロパティへの書き込みまたは値の変更ができます。
configurable
      
      false
      
      設定されている場合(デフォルト)、
defineProperty
      
      を2回呼び出すと、エラーがスローされます。
 var obj = {}; Object.defineProperty(obj, "foo", { value: "bar", }); Object.defineProperty(obj, "foo", { value: "foobar", }); // Uncaught TypeError: Cannot redefine property: foo
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
configurable
      
      true
      
      に設定されている
true
      
      、将来プロパティーを変更できます。 これは、書き込み不可のプロパティの値を変更するために使用できます。
 var obj = {}; Object.defineProperty(obj, "foo", { value: "bar", configurable: true, }); obj.foo = "foobar"; console.log(obj.foo); // logs "bar", write failed Object.defineProperty(obj, "foo", { value: "foobar", configurable: true, }); console.log(obj.foo); // logs "foobar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
また、
defineProperty
      
      定義された値が
for in
      
      ループで
defineProperty
      
      ないことに注意する必要があります。
 var i, inventory; inventory = { "apples": 10, "oranges": 13, }; Object.defineProperty(inventory, "strawberries", { value: 3, }); for (i in inventory) { console.log(i, inventory[i]); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
 apples 10 oranges 13
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      これを有効にするには、
enumerable
      
      プロパティを使用する必要があります
 var i, inventory; inventory = { "apples": 10, "oranges": 13, }; Object.defineProperty(inventory, "strawberries", { value: 3, enumerable: true, }); for (i in inventory) { console.log(i, inventory[i]); }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
 apples 10 oranges 13 strawberries 3
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      for in
      
      ループにプロパティが表示されるかどうかを確認するには、
isPropertyEnumerable
      
      を使用できます
 var i, inventory; inventory = { "apples": 10, "oranges": 13, }; Object.defineProperty(inventory, "strawberries", { value: 3, }); console.log(inventory.propertyIsEnumerable("apples")); //console logs true console.log(inventory.propertyIsEnumerable("strawberries")); //console logs false
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
propertyIsEnumerable
      
      呼び出しは、プロトタイプチェーンで上記で定義されたプロパティ、またはこのオブジェクトに対して他の方法で定義されていないプロパティに対しても
false
      
      を返しますが、これは明らかです。
最後に、
defineProperty
      
      の使用に関するいくつかの言葉:
set
      
      メソッドと
get
      
      アクセスメソッドを
writable: true
      
      に結合したり、
value
      
      と結合したりするのは間違い
value
      
      。 番号を使用してプロパティを定義すると、他の状況の場合と同様に、その番号が文字列に反映されます。
defineProperty
      
      を使用して、
value
      
      を関数として定義することもできます。
defineProperties
defineProperties
      
      もあります。 このメソッドを使用すると、一度に複数のプロパティを定義できます。 definePropertiesの使用と
defineProperties
      
      を比較する
defineProperties
      
      に
defineProperty
      
      ました。少なくともChromeでは、どのメソッドを使用するかに大きな違いはありませんでした。
 var foo = {} Object.defineProperties(foo, { bar: { value: "foo", writable: true, }, foo: { value: function() { console.log(this.bar); } }, }); foo.bar = "foobar"; foo.foo(); //logs "foobar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
Object.create
Object.create
      
      は
new
      
      の代替であり、特定のプロトタイプを使用してオブジェクトを作成できます。 この関数は2つの引数を取ります。1つ目はオブジェクトを作成するプロトタイプで、2つ目は
Object.defineProperties
      
      呼び出すときに使用されるハンドルと同じ
Object.defineProperties
      
       var prototypeDef = { protoBar: "protoBar", protoLog: function () { console.log(this.protoBar); } }; var propertiesDef = { instanceBar: { value: "instanceBar" }, instanceLog: { value: function () { console.log(this.instanceBar); } } } var foo = Object.create(prototypeDef, propertiesDef); foo.protoLog(); //logs "protoBar" foo.instanceLog(); //logs "instanceBar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
物性 記述子を使用して説明すると、プロトタイプの対応するプロパティが上書きされます。
 var prototypeDef = { bar: "protoBar", }; var propertiesDef = { bar: { value: "instanceBar", }, log: { value: function () { console.log(this.bar); } } } var foo = Object.create(prototypeDef, propertiesDef); foo.log(); //logs "instanceBar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
定義されたプロパティの値として
Array
      
      や
Object
      
      などの非プリミティブ型を使用すると、これらのプロパティが作成されたすべてのインスタンスと共有されるため、間違いになる可能性があります。
 var prototypeDef = { protoArray: [], }; var propertiesDef = { propertyArray: { value: [], } } var foo = Object.create(prototypeDef, propertiesDef); var bar = Object.create(prototypeDef, propertiesDef); foo.protoArray.push("foobar"); console.log(bar.protoArray); //logs ["foobar"] foo.propertyArray.push("foobar"); console.log(bar.propertyArray); //also logs ["foobar"]
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
これは、
null
      
      値で
propertyArray
      
      を初期化することで回避でき
null
      
      。その後、必要な配列を追加するか、たとえばゲッターを使用して何か流行に敏感なことを行います。
 var prototypeDef = { protoArray: [], }; var propertiesDef = { propertyArrayValue_: { value: null, writable: true }, propertyArray: { get: function () { if (!this.propertyArrayValue_) { this.propertyArrayValue_ = []; } return this.propertyArrayValue_; } } } var foo = Object.create(prototypeDef, propertiesDef); var bar = Object.create(prototypeDef, propertiesDef); foo.protoArray.push("foobar"); console.log(bar.protoArray); //logs ["foobar"] foo.propertyArray.push("foobar"); console.log(bar.propertyArray); //logs []
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
これは、変数の初期化とその定義を組み合わせるエレガントな方法です。 変数の初期化とともに変数の定義を実行することを好むと思いますが、これはコンストラクタで同じことを行うよりもはるかに良いでしょう。 過去に、初期化を実行する多くのコードがある巨大なコンストラクターを作成しました。
前の例は、
Object.create
      
      記述子の任意の値に渡される式は、記述子が定義されるときに実行されることを覚えておく必要があることを示しています。 これが、配列がクラスのすべてのインスタンスに共通になった理由です。 また、複数のプロパティが一緒に定義されている場合、固定された順序に頼らないことをお勧めします。 本当に必要な場合
Object.defineProperty
      
      つのプロパティを他のプロパティよりも先に定義する場合-この場合は、
Object.defineProperty
      
      を使用することをお
Object.defineProperty
      
      します。
Object.create
      
      はコンストラクター関数を呼び出さないため、
instanceof
      
      を使用してオブジェクトのIDを確認することはできなくなりました。 代わりに、オブジェクトの
prototype
      
      プロパティに対してチェックする
isPrototypeOf
      
      を使用できます。 これは、コンストラクターの場合はMyFunction.prototype、または
Object.create
      
      最初の引数として渡されるオブジェクトになります
 function Foo() { } var prototypeDef = { protoArray: [], }; var propertiesDef = { propertyArrayValue_: { value: null, writable: true }, propertyArray: { get: function () { if (!this.propertyArrayValue_) { this.propertyArrayValue_ = []; } return this.propertyArrayValue_; } } } var foo1 = new Foo(); //old way using instanceof works with constructors console.log(foo1 instanceof Foo); //logs true //You check against the prototype object, not the constructor function console.log(Foo.prototype.isPrototypeOf(foo1)); //true var foo2 = Object.create(prototypeDef, propertiesDef); //can't use instanceof with Object.create, test against prototype object... //...given as first agument to Object.create console.log(prototypeDef.isPrototypeOf(foo2)); //true
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
isPrototypeOf
      
      はプロトタイプチェーンを下降し、比較対象のオブジェクトと一致するものがあれば
true
      
      を返し
true
      
      。
 var foo1Proto = { foo: "foo", }; var foo2Proto = Object.create(foo1Proto); foo2Proto.bar = "bar"; var foo = Object.create(foo2Proto); console.log(foo.foo, foo.bar); //logs "foo bar" console.log(foo1Proto.isPrototypeOf(foo)); // logs true console.log(foo2Proto.isPrototypeOf(foo)); // logs true
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
オブジェクトの「シール」、「フリーズ」および拡張の防止
そのような可能性があるという理由だけで、ランダムなオブジェクトとクラスのインスタンスに任意のプロパティを追加すると、少なくともコードは良くなりません。 node.jsおよび最新のブラウザーでは、
defineProperty
      
      を使用して個々のプロパティへの変更を制限する機能に加えて、オブジェクト全体への変更を制限する機能があります。
Object.preventExtensions
      
      、
Object.seal
      
      および
Object.freeze
      
      これらの各メソッドは、オブジェクトの変更に対してより厳しい制限を課します。 厳格モードでは、これらのメソッドによって課せられた制限に違反すると、エラーがスローされます。そうでない場合、エラーは「静かに」発生します。
Object.preventExtensions
      
      メソッドは、オブジェクトに新しいプロパティを追加できないようにします。 書き込み用に開いているプロパティを変更したり、カスタマイズ可能なプロパティを削除したりすることを妨げません。 さらに、
Object.preventExtensions
      
      は、既存のプロパティを変更するために
Object.defineProperty
      
      の呼び出しを使用することを不可能にしません。
 var obj = { foo: "foo", }; obj.bar = "bar"; console.log(obj); // logs Object {foo: "foo", bar: "bar"} Object.preventExtensions(obj); delete obj.bar; console.log(obj); // logs Object {foo: "foo"} obj.bar = "bar"; console.log(obj); // still logs Object {foo: "foo"} obj.foo = "foobar" console.log(obj); // logs {foo: "foobar"} can still change values
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
(オブジェクトの最終値のみがコンソールに表示されるため、開発者コンソールを開いた状態で以前のjsfiddleを再起動する必要があることに注意してください)
Object.seal
      
      はさらに
Object.seal
      
      進みます。
Object.preventExtensions
      
      よりも。 このメソッドは、オブジェクトへの新しいプロパティの追加を禁止することに加えて、既存のプロパティをさらに構成および削除する機能も制限します。 オブジェクトが封印されると、
defineProperty
      
      既存のプロパティを変更できなくなります。 上記のように、strictモードでこれらの禁止事項に違反すると、エラーがスローされます。
 "use strict"; var obj = {}; Object.defineProperty(obj, "foo", { value: "foo" }); Object.seal(obj); //Uncaught TypeError: Cannot redefine property: foo Object.defineProperty(obj, "foo", { value: "bar" });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
また、プロパティが元々カスタマイズ可能であったとしても、プロパティを削除することはできません。 あとは、プロパティ値を変更するだけです。
 "use strict"; var obj = {}; Object.defineProperty(obj, "foo", { value: "foo", writable: true, configurable: true, }); Object.seal(obj); console.log(obj.foo); //logs "foo" obj.foo = "bar"; console.log(obj.foo); //logs "bar" delete obj.foo; //TypeError, cannot delete
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
最終的に、
Object.freeze
      
      はオブジェクトを変更から完全に保護します。 凍結された「オブジェクト」のプロパティ値を追加、削除、または変更することはできません。
Object.defineProperty
      
      を使用してオブジェクトの既存のプロパティの値を変更する方法もありません。
 "use strict"; var obj = { foo: "foo1" }; Object.freeze(obj); //All of the following will fail, and result in errors in strict mode obj.foo = "foo2"; //cannot change values obj.bar = "bar"; //cannot add a property delete obj.bar; //cannot delete a property //cannot call defineProperty on a frozen object Object.defineProperty(obj, "foo", { value: "foo2" });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
オブジェクトが「フリーズ」、「シール」、または展開から保護されているかどうかを確認できるメソッドは次のとおりです。
Object.isFrozen
      
      、
Object.isSealed
      
      および
Object.isExtensible
      
      valueOfおよびtoString
JavaScriptがプリミティブな値を取得することを期待している場合、
valueOf
      
      と
toString
      
      を使用して、コンテキスト内のオブジェクトの動作をカスタマイズできます。
toString
      
      の使用例を次に示します。
 function Foo (stuff) { this.stuff = stuff; } Foo.prototype.toString = function () { return this.stuff; } var f = new Foo("foo"); console.log(f + "bar"); //logs "foobar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
そして
valueOf
      
      :
 function Foo (stuff) { this.stuff = stuff; } Foo.prototype.valueOf = function () { return this.stuff.length; } var f = new Foo("foo"); console.log(1 + f); //logs 4 (length of "foo" + 1);
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
これらの2つの方法の使用を組み合わせると、予期しない結果を得ることができます。
 function Foo (stuff) { this.stuff = stuff; } Foo.prototype.valueOf = function () { return this.stuff.length; } Foo.prototype.toString = function () { return this.stuff; } var f = new Foo("foo"); console.log(f + "bar"); //logs "3bar" instead of "foobar" console.log(1 + f); //logs 4 (length of "foo" + 1);
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
toString
      
      を使用する適切な方法は、オブジェクトをハッシュ可能にすることです。
 function Foo (stuff) { this.stuff = stuff; } Foo.prototype.toString = function () { return this.stuff; } var f = new Foo("foo"); var obj = {}; obj[f] = true; console.log(obj); //logs {foo: true}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
getOwnPropertyNamesおよびキー
オブジェクトのすべてのプロパティを取得するには、
Object.getOwnPropertyNames
      
      を使用できます。 Pythonに精通している場合、
Object.keys
      
      メソッドも存在しますが、一般的には辞書の
keys
      
      メソッドに似てい
keys
      
      。
Object.keys
      
      と
Object.getOwnPropertyNames
      
      の主な違いは、後者が「列挙不可能な」プロパティを返すことです。これらのプロパティは
for in
      
      ループの
for in
      
      時に考慮されません。
 var obj = { foo: "foo", }; Object.defineProperty(obj, "bar", { value: "bar" }); console.log(Object.getOwnPropertyNames(obj)); //logs ["foo", "bar"] console.log(Object.keys(obj)); //logs ["foo"]
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
記号
Symbol
      
      は、ECMAScrpt 6ハーモニーで定義されている特別な新しいプリミティブであり、JavaScriptの次の反復で使用可能になります。 今すぐChrome CanaryとFirefox Nightlyで試してみてください。次のjsfiddleの例は、少なくとも2014年8月のこの記事を書いている時点では、これらのブラウザーでのみ機能します。
Symbol
      
      は、オブジェクトのプロパティを作成および参照する方法として使用できます。
 var obj = {}; var foo = Symbol("foo"); obj[foo] = "foobar"; console.log(obj[foo]); //logs "foobar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
Symbol
      
      はユニークで不変です
 //console logs false, symbols are unique: console.log(Symbol("foo") === Symbol("foo"));
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
Symbol
      
      は
Object.defineProperty
      
      で使用できます:
 var obj = {}; var foo = Symbol("foo"); Object.defineProperty(obj, foo, { value: "foobar", }); console.log(obj[foo]); //logs "foobar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
Symbol
      
      定義されたプロパティは
for in
      
      ループで繰り返されませんが、
hasOwnProperty
      
      呼び出しは正常に機能します。
 var obj = {}; var foo = Symbol("foo"); Object.defineProperty(obj, foo, { value: "foobar", }); console.log(obj.hasOwnProperty(foo)); //logs true
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
Symbol
      
      は
Object.getOwnPropertyNames
      
      関数によって返される配列に入りませんが、
Object. getOwnPropertySymbols
      
      メソッドがあり
Object. getOwnPropertySymbols
      
      Object. getOwnPropertySymbols
      
       var obj = {}; var foo = Symbol("foo"); Object.defineProperty(obj, foo, { value: "foobar", }); //console logs [] console.log(Object.getOwnPropertyNames(obj)); //console logs [Symbol(foo)] console.log(Object.getOwnPropertySymbols(obj));
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
Symbol
      
      を使用すると、偶発的な変更からプロパティを保護するだけでなく、通常の操作中に表示したくない場合にも便利です。 可能性のあるすべての機会について真剣に考えたことはありませんが、まだまだあると思います。
プロキシ
ECMAScript 6のもう1つの革新は
Proxy
      
      です。 2014年8月現在、プロキシはFirefoxでのみ機能します。 次のjsfiddleの例はFirefoxでのみ機能し、実際、インストールしたFirefoxベータ版でテストしました。
プロキシはすべてのプロパティを取得する機会を提供し、例に注意を払うので、プロキシは楽しいと感じます:
 var obj = { foo: "foo", }; var handler = { get: function (target, name) { if (target.hasOwnProperty(name)) { return target[name]; } return "foobar"; }, }; var p = new Proxy(obj, handler); console.log(p.foo); //logs "foo" console.log(p.bar); //logs "foobar" console.log(p.asdf); //logs "foobar"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      jsfiddle
この例では、
obj
      
      オブジェクトをプロキシしています。 作成されたオブジェクトとの相互作用を処理する
handler
      
      オブジェクトを作成します。
get
      
      handlerメソッドは非常に簡単です。 オブジェクトと、アクセスされるプロパティの名前を受け取ります。 この情報はいつでも返すことができますが、この例では、キーがある場合は実際の値が返され、キーがない場合はfoobarが返されます。 私は、
Scala
      
      ような
switch
      
      ようなものの1つである、プロキシを使用する可能性と興味深い方法の巨大なフィールドを見ています。
プロキシの別のアプリケーションはテストです。
get
      
      加え
has
      
      、
set
      
      、
has
      
      、および他のハンドラー
has
      
      あります。 プロキシがより良いサポートを得るとき、私は彼らに私のブログに全体の投稿をすることをheしません。 MDNプロキシのドキュメントを見て、記載されている例に注意することをお勧めします。
とりわけ、jsconfからの優れたプロキシレポートもあります。 スライド
JavaScriptでオブジェクトを使用する方法は、ランダムデータを単に保存するよりも多くあります。 プロパティを定義するための強力な方法は既に利用可能であり、将来、JavaScriptコードの記述方法をプロキシがどのように変更できるかを考えるとわかるように、さらに興味深いものがあります。 明確化やコメントがありましたら、それについて私に知らせてください。ここに私のツイッターがあります:@bjorntipling。