2016-02-24 8 views
13

Javascriptで配列の変更を監視するのは比較的簡単です。Proxyオブジェクトを使用したJavascript配列の変更の検出

私が使用して一つの方法は、このようなものです:

// subscribe to add, update, delete, and splice changes 
Array.observe(viewHelpFiles, function(changes) { 
    // handle changes... in this case, we'll just log them 
    changes.forEach(function(change) { 
    console.log(Object.keys(change).reduce(function(p, c) { 
     if (c !== "object" && c in change) { 
     p.push(c + ": " + JSON.stringify(change[c])); 
     } 
     return p; 
    }, []).join(", ")); 
    }); 
}); 

はしかし、私は最近Array.observeが廃止されていることを読んだことがあると私たちは、アレイプロキシオブジェクトの変化を検出するにはどうすればよいproxy object instead.

を使用する必要があります?どのような例を見つけられないのですか?

+0

のように気にいらを行うことができますが、プロキシは、現在だけでサポートされていることをこのhttps://gist.github.com/ebidel/1b553d571f924da2da06 – elclanrs

+1

注意を得ましたFirefox、および少数の蒸散器を使用していますが、これは実動コードで使用するものではありません。 – adeneo

+0

Internet Explorerを除くすべての主要なブラウザでプロキシがサポートされるようになりました。 –

答えて

23

MDN pageから読んだところから、どのオブジェクトの変更もすべて処理できる汎用ハンドラを作成できます。

ある意味では、配列から値を取得するか値を設定するたびに介入するインターセプタを作成します。変更を追跡する独自のロジックを記述することができます。

getting push for 
getting length for 
setting 0 for with value Test 
setting length for Test with value 1 
getting 0 for Test 
Test 

プロキシの警告を、オブジェクトに定義されているすべてが、使用時に観察することができ、傍受されることである。その後、出力

var arrayChangeHandler = { 
 
    get: function(target, property) { 
 
    console.log('getting ' + property + ' for ' + target); 
 
    // property is index in this case 
 
    return target[property]; 
 
    }, 
 
    set: function(target, property, value, receiver) { 
 
    console.log('setting ' + property + ' for ' + target + ' with value ' + value); 
 
    target[property] = value; 
 
    // you have to return true to accept the changes 
 
    return true; 
 
    } 
 
}; 
 

 
var originalArray = []; 
 
var proxyToArray = new Proxy(originalArray, arrayChangeHandler); 
 

 
proxyToArray.push('Test'); 
 
console.log(proxyToArray[0]); 
 

 
// pushing to the original array won't go through the proxy methods 
 
originalArray.push('test2'); 
 

 
// the will however contain the same data, 
 
// as the items get added to the referenced array 
 
console.log('Both proxy and original array have the same content? ' 
 
    + (proxyToArray.join(',') === originalArray.join(','))); 
 

 
// expect false here, as strict equality is incorrect 
 
console.log('They strict equal to eachother? ' + (proxyToArray === originalArray));

push方法。

プロキシされる元のオブジェクトは変更されず、元のオブジェクトに対して行われた変更はプロキシによってキャッチされません。

+1

警告、IE11ではサポートされていません。 – Chexpir

+2

@Chexpir真実、MDNによれば、それはIEでも完全にサポートされていませんが、現在のMSブラウザであるEdgeによってサポートされるべきです – Icepickle

+0

しかし、あなたはプロキシを作成してプロキシを転送しますアレイに。問題はアレイ自体を実際に観察する方法です。プロキシ "arrayToObserve"の命名は誤解を招きます。これらのプロキシと配列は、全く異なる2つのオブジェクトです。 – Winchestro

0

あなたは、私がグーグルで「プロキシ観察」を探したこの

new Proxy([], { 
    get(target, prop) { 
     const val = target[prop]; 
     if (typeof val === 'function') { 
      if (['push', 'unshift'].includes(prop)) { 
       return function (el) { 
        console.log('this is a array modification'); 
        return Array.prototype[prop].apply(target, arguments); 
       } 
      } 
      if (['pop'].includes(prop)) { 
       return function() { 
        const el = Array.prototype[prop].apply(target, arguments); 
        console.log('this is a array modification'); 
        return el; 
       } 
      } 
      return val.bind(target); 
     } 
     return val; 
    } 
});