検索

JavaScriptでのwithの使い方

Jun 15, 2018 pm 05:03 PM
jswith

js の with キーワードといえば、多くの友人の第一印象は、with キーワードの機能はスコープの変更であり、最も重要な点は with キーワードの使用は推奨されないということでしょう。 with キーワードは推奨されないと聞くと、多くの人は with キーワードを無視して、無視して使用すればよいと考えます。しかし、コードや面接の質問を見ると、with キーワードに関連した質問が出てくることがあります。これまで経験したことのない落とし穴がたくさんあるため、with キーワードについて話しておく必要があります。

with の基本的な使用法 with ステートメントの本来の目的は、レベルごとのオブジェクト アクセスに名前空間スタイルの短縮メソッドを提供することです。つまり、指定されたコード領域で、オブジェクトが を介して直接呼び出されます。ノード名。

with は通常、オブジェクト自体を繰り返し参照せずに、同じオブジェクト内の複数のプロパティを繰り返し参照するためのショートカットとして使用されます。
例えば、現在こんなオブジェクトがあります:

var obj = {
    a: 1,
    b: 2,
    c: 3};

objの各項目の値を変更したい場合、一般的な書き方はこんな感じです:
// 重复写了3次的“obj”obj.a = 2;
obj.b = 3;
obj.c = 4;

そしてwithの書き方を使うと、単純なショートカットになります

with (obj) {
    a = 3;
    b = 4;
    c = 5;
}

このコードでは、with ステートメントを使用して obj オブジェクトを関連付けています。つまり、with コード ブロック内では、ローカル変数がローカル変数と同じ名前である場合、各変数は最初にローカル変数とみなされます。 obj オブジェクトのプロパティの場合、このローカル変数は obj オブジェクト属性を指します。

withの欠点

上記の例では、withがコードを非常に単純化するのに役立つことがわかります。しかし、なぜ推奨されないのでしょうか? with の欠点について話しましょう:


データ漏洩につながる

コードの次の部分を見てみましょう
function foo(obj) {
    with (obj) {
        a = 2;
    }
}var o1 = {
    a: 3};var o2 = {
    b: 3}
foo(o1);
console.log(o1.a);  //2foo(o2);
console.log(o2.a);  //underfinedconsole.log(a);     //不好,a被泄漏到全局作用域上了
まず、上記のコードを分析しましょう。この例では、2 つのオブジェクト o1 と o2 が作成されます。そのうちの 1 つは a 属性を持っていますが、もう 1 つは持っていません。 foo(obj) 関数は、オブジェクト参照である obj の仮パラメータを受け入れ、オブジェクトに対して with(obj) {...} を実行します。 with ブロック内には、実際には LHS 参照である a への字句参照があり、それに 2 が割り当てられます。

o1 を渡すと、a = 2 代入操作で o1.a が見つかり、それに 2 が代入されます。 o2 が渡されると、o2 にはプロパティがないため、このプロパティは作成されず、o2.a は未定義のままになります。

foo(obj) 函数接受一个 obj 的形参,该参数是一个对象引用,并对该对象医用执行了 with(obj) {...}。在 with 块内部,对 a 有一个词法引用,实际上是一个 LHS引用,将 2 赋值给了它。
  当我们将 o1 传递进去,a = 2 赋值操作找到了 o1.a 并将 2 赋值给它。而当 o2 传递进去,o2 并没有 a 的属性,因此不会创建这个属性,o2.a 保持 undefined。


  但为什么对 o2的操作会导致数据的泄漏呢?
  这里需要回到对 LHS查询 的机制问题(详情可移步  JavaScript中的LHS和RHS查询)。
  当我们传递 o2 给 with 时,with 所声明的作用域是 o2, 从这个作用域开始对 a 进行 LHS查询。o2 的作用域、foo(…) 的作用域和全局作用域中都没有找到标识符 a,因此在非严格模式下,会自动在全局作用域创建一个全局变量),在严格模式下,会抛出ReferenceError しかし、なぜo2の運用が情報漏洩につながるのでしょうか?

ここで、LHS クエリ のメカニズムに戻る必要があります (詳細については、JavaScript の LHS クエリと RHS クエリを参照してください)。
o2 を with に渡すと、with で宣言されたスコープは o2 となり、a の LHS クエリ はこのスコープから開始されます。識別子 a は、o2 のスコープ、foo(...) のスコープ、およびグローバル スコープでは見つからないため、非厳密モードでは、グローバル変数がグローバル スコープに自動的に作成されます。スコープ)、厳密モードでは、ReferenceError 例外がスローされます。

withが推奨されないもう1つの理由は、です。厳密モードでは、eval(…) の間接的または安全でない使用と同様に、with は完全に禁止されています。

パフォーマンスの低下

with は実行時にスコープを変更または新規作成するため、作成時に定義された他の字句スコープを騙します。上記のデータ漏洩の可能性はありますが、少し注意することで回避できます。
答えは「ノー」です。具体的な理由については、まずコードの次の部分を見てみましょう。

次のコードをコピーして直接実行できます

<script>function func() {
    console.time("func");    var obj = {
        a: [1, 2, 3]
    };    for(var i = 0; i < 100000; i++)
    {        var v = obj.a[0];
    }
    console.timeEnd("func");
}
func();function funcWith() {
    console.time("funcWith");    var obj = {
        a: [1, 2, 3]
    };    with(obj) {        for(var i = 0; i < 100000; i++) {            var v = a[0];
        }
    }
    console.timeEnd("funcWith");
}
funcWith();</script>

そして、テスト効果:

JavaScriptでのwithの使い方


🎜🎜

同じロジックを処理するコードの実行時間は、ありなしの場合はわずか 4.63 ミリ秒です。 with使用時の使用時間は81.87msと長いです。


これはなぜですか?
その理由は、JavaScript エンジンがコンパイル段階でいくつかのパフォーマンスの最適化を実行するためです。これらの最適化の一部は、コードをその語彙集に基づいて静的に分析し、すべての変数と関数が定義されている場所を事前に決定して、実行中に識別子をすぐに見つけられるようにすることに依存しています。
しかし、エンジンがコード内で with を見つけた場合、新しい字句スコープの作成に使用された with に渡されたオブジェクトの内容を知る方法がないため、識別子の位置に関する判断は無効であると単純に想定できます。は。
最も悲観的なケースは、with が出現した場合、すべての最適化が無意味になる可能性があるということです。したがって、エンジンが採用する最も単純なアプローチは、最適化をまったく行わないことです。コードで with または eval() を多量に使用すると、間違いなく実行が非常に遅くなります。エンジンがこれらの悲観的な状況による副作用を最小限に抑えようとしてどれほど賢明であっても、これらの最適化がなければコードの実行が遅くなるという事実を避けることはできません この記事では、JavaScript での with の使用法について説明します。その他の関連コンテンツについては、php 中国語 Web サイトを参照してください。

関連する推奨事項:

js と php のネスト


js はデフォルトのイベントを防ぎ、js はバブリングイベントをブロックする例を共有します


js 関数の一般的な書き込みメソッドと呼び出しメソッド

以上がJavaScriptでのwithの使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptをインストールするにはどうすればよいですか?JavaScriptをインストールするにはどうすればよいですか?Apr 05, 2025 am 12:16 AM

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン