Symbol.unscopables

Symbol.unscopables ウェルノウンシンボルは、自身のプロパティ名と継承されたプロパティ名が、関連付けられたオブジェクトの with 環境バインディングから除外されているオブジェクトの値を指定するために使用されます。

試してみましょう

解説

The @@unscopables シンボル (Symbol.unscopables) は、 with 環境バインディングでプロパティ名が語彙的変数として公開されないようにするために、任意のオブジェクトに定義することができます。厳格モードを使用している場合、 with 文は使用できず、このシンボルも必要ないことに注意してください。

unscopables オブジェクトでプロパティを true に設定すると、そのプロパティはスコープ不能になり、語彙的スコープ変数には表示されません。プロパティを false に設定すると、 scopable になり、語彙的スコープ変数に表示されます。

Symbol.unscopables のプロパティ属性
書込可能 不可
列挙可能 不可
設定可能 不可

with 文内のスコープ

次のコードは、ES5 以下であれば正しく動作します。しかし、 ECMAScript 2015(ES6)以降では、Array.prototype.keys() メソッドが導入されました。これは、with 環境内で "keys" はメソッドであり変数ではないことを意味します。これが unscopable シンボルを導入すべき時です。ビルトインの unscopables 設定は、配列のメソッドのいくつかが with 環境のスコープに入らないようにするために、Array.prototype[@@unscopables] として実装されています。

js
var keys = [];

with (Array.prototype) {
  keys.push("something");
}

Object.keys(Array.prototype[Symbol.unscopables]);
// ["copyWithin", "entries", "fill", "find", "findIndex",
//  "includes", "keys", "values"]

オブジェクト内の unscopables

自分のオブジェクトに unscopables を設定することもできます。

js
var obj = {
  foo: 1,
  bar: 2,
};

obj[Symbol.unscopables] = {
  foo: false,
  bar: true,
};

with (obj) {
  console.log(foo); // 1
  console.log(bar); // ReferenceError: bar is not defined
}

仕様書

Specification
ECMAScript Language Specification
# sec-symbol.unscopables

ブラウザーの互換性

BCD tables only load in the browser

関連情報