with 非推奨

with文は、複雑なバグの要因になる事と互換性の問題から使用は避けるべきです。 詳細については、「説明」の「曖昧さによる欠点」の段落を参照してください。

with文は文のスコープチェーンを拡張します。

文法

with (expression) {
  statement
}
引数 説明
expression 文が評価される際に、追加のスコープチェーンとして使用される式を指定します。 式を囲む丸括弧は必須です。
statement 任意の式を指定します。 複数行の式で実行するには、ブロック文({ ... })を使用してそれらの文をブロック化します。

説明

JavaScriptは、非修飾名を含んでいるスクリプトまたは関数の実行コンテキストに関連付けられたスコープチェーンを検索することで、非修飾名を調べます。 'with'文は、その本文が評価されている区間、そのスコープチェーンの先頭に指定されたオブジェクトを追加します。

もし、本文内で使用されている非修飾名がスコープチェーン内のプロパティにマッチした場合、 それはプロパティとそのプロパティを含むオブジェクトにバインドされます。 そうでなければ、ReferenceErrorがスローされます。

withの使用は非推奨とされており、 ECMAScript 5のstrict modeでは使用が禁止されています。 代わりに、値にアクセスしたいプロパティを持つオブジェクトを、一時的に割り当てることが推奨されています。

パフォーマンスの利点と欠点

利点:
with文は、長いオブジェクト参照の文字列の繰り返しを減らすことで、 パフォーマンスのペナルティー無しにファイルサイズを減らす手助けをしてくれます。 'with'によるスコープチェーンの変更は、処理コストが高いものではありません。 'with'の使用は、インタプリタのオブジェクト参照の繰り返しの解析処理を和らげてくれます。 ただし、希望するオブジェクトを参照する一時的な変数を使用することで、 ほとんどのケースでこの利点を得られる事に注意してください。

欠点:
with文は、名前を調べる全ての場合において、まず指定されたオブジェクトを検索するように強制します。 そのため、指定されたオブジェクトのメンバーでは無い識別名は、'with'ブロック内では検索するのに余計に時間が掛かります。 パフォーマンスが重要なケースでは、'with'は指定されたオブジェクトのメンバーのみにアクセスするコードのブロックのみで使用するべきです。

曖昧さによる欠点

欠点:
with文は人間の読み手にとってまたはJavaScriptコンパイラにとって、 スコープチェーンに沿って見つけられる非修飾名なのか、 またそうであれば、その中のオブジェクトであるのかを決定しづらいものにします。 下記の例の場合、

function f(x, o) {
  with (o)
    print(x);
}

fが呼び出された場合にのみ、xが有るか無いかが関係し、 もし有れば、正当な第1引数であるxの名前を持つ、 o内のものが、または(そのようなプロパティが存在しなければ)fの動作オブジェクト内のものの、 どちらかが使用されます。 もし、2つ目の引数として渡すoオブジェクトにxの定義を忘れてしまった場合、 またはそれに類するバグや間違いがあった場合に、エラーが発生すること無く、 思いも掛けない結果を得ることになるでしょう。

欠点:
withを使用したコードは、特にプレーンオブジェクト以外で使用された場合に、 前方互換性を持たない可能性があります。 次の例で考えてみます。

function f(foo, values) {
    with (foo) {
        console.log(values)
    }
}

もし、ECMAScript 5の環境でf([1,2,3], obj)を呼び出すと、 with文内部のvaluesは、objを参照します。 ただし、ECMAScript 6ではArray.prototypevaluesプロパティが導入されます。(そのため、各配列で利用可能)。 そのため、ECMAScript 6をサポートするJavaScriptの環境では、 with文内部のvaluesは、[1,2,3].valuesを参照します。

下記のwith文は、Mathオブジェクトがデフォルトのオブジェクトであることを指定し、 withの文中ではPIプロパティとcossinメソッドをオブジェクトの指定無しに参照しています。 JavaScriptはこれらの参照はMathオブジェクトであるとみなします。

var a, x, y;
var r = 10;

with (Math) {
  a = PI * r * r;
  x = r * cos(PI);
  y = r * sin(PI / 2);
}

仕様

ブラウザ互換性

デスクトップ
機能 Chrome Firefox
(Gecko)
IE Opera Safari
基本
モバイル
機能 Android Chrome for
Android
Firefox
Mobile
IE
Mobile
Opera
Mobile
Safari
Mobile
基本

関連項目

 Back to top

© 2017 Mozilla Contributors
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.

このページは、ページトップのURL先のMozilla Developer Network(以下、MDN)のコンテンツを翻訳した内容を基に構成されています。 構成について異なる点も含まれますので、下記の項目を確認し、必要に応じて元のコンテンツをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • 特定のブラウザに特化しすぎている情報やあまりにも古い情報、 または試験的に導入されているようなAPIや機能については、省略していることがあります。
  • 例やデモについて、実際にページ内で動作させる関係で一部ソースコードを変更している場合や、 その例で使用しているコンテンツの単語や文章などを日本人向けに変更しいてる場合があります。
  • MDNの更新頻度が高いため、元のコンテンツと比べ情報が古くなっている可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報の追記を行っている事があります。