 
      私のAtomJSフレームワークでは、アクセッター(ゲッターとセッター)を積極的に使用しています。
Foo = atom.Class({ get bar () { return this._bar; }, set bar (bar) { this._bar = bar; } });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     理論についてはすでに説明しましたが、トピックでは、すべての最新のブラウザーでそれらを動作させる方法、つまりInternet Explorer 9が
__defineSetter__
      
      および同様のメソッドについて何も知らないという事実で状況を解決する方法について説明します。
取得 / 設定
幸いなことに、この点で、すべてのブラウザーはほぼ同じです。 IE9 +、Opera10 +、Fx3.5 +、Chrome-すべてこのエントリをサポートし、動作と構文は同じです。 唯一のものは、Internet Explorer 9がポップアップする場合、「
  ':'
      
      'が
  ':'
      
      "-ブラウザが「Interner Explorer 7」の
defineProperty
ここで複雑なことはありません
非標準の場合
 __defineSetter__
      
       __defineSetter__
      
      および
 __defineGetter__
      
       __defineGetter__
      
      は、EcmaScript5- Object.definePropertyの代替です 。 デフォルトでは、オブジェクトの
configurable
      
      および
enumerable
      
      プロパティはtrueとして宣言されているため、標準の代替を簡単に記述できます。
 instance.__defineSetter__(propertyName, setterFn); instance.__defineGetter__(propertyName, getterFn); // => Object.defineProperty(instance, propertyName, { set: setterFn, get: getterFn, enumerable : true, configurable: true });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      getOwnPropertyDescriptor
非標準の場合
 __lookupSetter__
      
       __lookupSetter__
      
      および
 __lookupGetter__
      
       __lookupGetter__
      
      には、EcmaScript5- Object.getOwnPropertyDescriptorの代替もあります。
すべてが少し喜びではありませんが、重要ではありません。 秘密は、
__lookup*__
      
      はプロトタイプチェーン全体に沿ってアクセサを検索するのに対し、
getOwnPropertyDescriptor
      
      は個人のプロパティでのみ検索することです。
指定されたオブジェクトの独自のプロパティ(つまり、オブジェクトのプロトタイプチェーンに沿って存在するのではなく、オブジェクトに直接存在するプロパティ)のプロパティ記述子を返します。
つまり、 次の状況があります 。
 var MyClass = function () {}; MyClass.prototype = { get foo() { return 42; } }; var instance = new MyClass(); console.log(instance.__lookupGetter__('foo')); // function foo() { return 42; } console.log(Object.getOwnPropertyDescriptor(instance, 'foo')); // undefined
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      ゲッターには実際には次のものがあります:
 console.log(instance.foo); // 42
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      1.非標準プロパティのより正確かつ論理的な動作
2.私のフレームワークのアイデアにより適しています。
3.すべてのブラウザが同じように動作することが重要です。 それほど重要ではない
したがって、
null
      
      、または特定のプロパティまたはアクセサに到達するまで、 Object.getPrototypeOfメソッドを使用してプロトタイプチェーン全体を再帰的に処理します。
 function getPropertyDescriptor (from, key) { var descriptor = Object.getOwnPropertyDescriptor(from, key); if (!descriptor) { //     -       var proto = Object.getPrototypeOf(from); if (proto) return getPropertyDescriptor(proto, key); //   , ,       (   ) } else if ( descriptor.set || descriptor.get ) { return { set: descriptor.set, get: descriptor.get }; } //    ,       return null; };
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      すべてをライブラリに入れる
これで、取得した知識を適用して、ブラウザ間のアクセサー用のライブラリを作成できます。
私の個人的な観察によると、非標準の方法は少し速く動作し、必要なハックも少ないので、デフォルトとして採用しましょう。
また、私は名前の
lookup
      
      と
define
      
      好きです-それらは簡潔で理解しやすいので、私たちはそれらを使用する理由です。
2つの異なる関数を作成するだけで、毎回余分なチェックを行わないため、各メソッドのルックアップ関数の内容は根本的に異なります。
 (function (Object) { var standard = !!Object.getOwnPropertyDescriptor, nonStandard = !!{}.__defineGetter__; if (!standard && !nonStandard) throw new Error('Accessors are not supported'); var lookup = nonStandard ? function (from, key) { var g = from.__lookupGetter__(key), s = from.__lookupSetter__(key); return ( g || s ) ? { get: g, set: s } : null; } : function (from, key) { var descriptor = Object.getOwnPropertyDescriptor(from, key); if (!descriptor) { var proto = Object.getPrototypeOf(from); if (proto) return accessors.lookup(proto, key); } else if ( descriptor.set || descriptor.get ) { return { set: descriptor.set, get: descriptor.get }; } return null; }; var define = nonStandard ? function (object, prop, descriptor) { if (descriptor) { if (descriptor.get) object.__defineGetter__(prop, descriptor.get); if (descriptor.set) object.__defineSetter__(prop, descriptor.set); } return object; } : function (object, prop, descriptor) { if (descriptor) { var desc = { get: descriptor.get, set: descriptor.set, configurable: true, enumerable: true }; Object.defineProperty(object, prop, desc); } return object; }; this.accessors = { lookup: lookup, define: define }; })(Object);
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      これで、オブジェクトでアクセサーを宣言できます。
 MyClass = function (param) { var property = param; accessors.define(this, 'property', { set: function (value) { property = value; }, get: function () { return property; } }); }; var instance = new MyClass(42); console.log(instance.property); // 42 console.log(accessors.lookup(instance, 'property')); // getter+setter
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      継承
inherit
      
      メソッドを追加して、ライブラリを少し拡張してみましょう。 これは、fromオブジェクトから
key
      
      という名前のプロパティアクセサーを受け取り、toオブジェクトに追加します。 成功した場合は
true
      
      、そうでない場合は
false
      
      返し
true
      
      。
  this.accessors = { lookup: lookup, define: define, inherit: function (from, to, key) { var a = accessors.lookup(from, key); if ( a ) { accessors.define(to, key, a); return true; } return false; } };
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      このメソッドは、
jQuery.extend
      
      をサポートする
MooTools
      
      jQuery.extend
      
      または
Object.merge
      
      類似物を作成するのに役立ちますが、すべての通常のフレームワークはそれらについて何も知りません。
 var object = jQuery.extend({}, { get foo(){ return null; } }); console.log( object.__lookupGetter__('foo') ); // undefined console.log( object.foo ); // null
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      独自のバージョンを作成します(注意、このオプションは教育目的で作成されたものであり、実際のアプリケーションでは使用しないでください)
 function extend(from, to) { for (var i in to) { //    if (!accessors.inherit(from, to, i)) { //     -    from[i] = to[i]; } } return from; }; var object = extend({}, { get foo(){ return null; } }); console.log( object.__lookupGetter__('foo') ); // getter console.log( object.foo ); // null
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      おわりに
とても快適です。 高度に特化された2つの非常に強力なフレームワーク、 AtomJSとLibCanvasがあり、アクセサーの使用が完全に成果を上げました。 あなたが9番目のバージョン以下のロバを放棄する余裕があるなら-それは価値がある、たくさんの喜びを得る。
このトピックで説明されているソリューションは、わずかに拡張されており、当初はAtomJS-Accessorsプラグインとして実装されていました 。