@@unscopablesが実装された
概要
with文に与えたオブジェクトの特定のプロパティがスコープに含まれることを防ぐための、
ビルトイン"unscopables"シンボルが実装された。
例
@@unscopablesプロパティのオブジェクトが有する名前のプロパティは、値がTruthyならスコープから外される。
var a = 'unscopable', b = 'unscopable', c = 'unscopable' var obj = { a: 'scopable', b: 'scopable', c: 'scopable', } obj[Symbol.unscopables] = { b: true, c: false } with (obj) { console.log(a, b, c) } /* log "scopable" "unscopable" "scopable" */
何故必要なのか
ES2015で増えたメソッドとの兼ね合いで、with文が使われた古いコードを壊し得るため。(実際に問題が出た)
var ary = [] var keys = [1, 2, 3] with (ary) { keys.push(4) }
このwith文中の『keys』は、ES2015では『Array.prototype.keys』を参照してしまうので『.push(4)』でエラーになってしまう。
そのため『Array.prototype[@@unscopables]』には、新しく追加されたメソッドが登録されており、この問題を回避している。
console.log( Array.prototype[Symbol.unscopables] ) /* log { copyWithin : true, entries : true, fill : true, find : true, findIndex : true, includes : true, keys : true, values : true, } */
意外な使い道
HTML要素のon~属性に記述するコードは、その要素やdocumentがスコープチェーンに入るが、それはwith文で囲まれたような実装になっていることが多い。
そこで、以下のようにdocumentの余計なプロパティがスコープに入ることを防ぐ為に使えるかもしれない。
<!-- 選択された画像ファイルを表示したい --> <input type="file" onchange="nextSibling.src = URL.createObjectURL(files[0])"><img> <!-- しかし、「URL」が「window.URL」ではなく「document.URL」を指してしまうのでエラーになる --> <script> document[Symbol.unscopables] = { URL: true } // これでdocument.URLがスコープに含まれることを回避できる。 </script>
実装されるバージョン
V8 (3.28.62) 3.28.64(デフォルト有効) 4.3.65(値がTruthyかどうか見るようになった)