with( document){
var bd=body,
links=getElementsByTagName("a"),
i=0,
len=links.length>while(i < ; len){
update(links[i ]);
getElementById("btnInit").onclick=function(){
doSomething();
}
}
ここで width ステートメントは、ドキュメントを複数回記述することを避けるために使用されており、効率的であるように見えますが、実際にはパフォーマンスの問題が発生します。
コードが with ステートメントまで実行されると、ランタイム コンテキストのスコープ チェーンが一時的に変更されます。パラメーターで指定されたオブジェクトのすべてのプロパティを含む新しい可変オブジェクトが作成されます。このオブジェクトはスコープ チェーンの先頭にプッシュされます。つまり、関数のすべてのローカル変数が 2 番目のスコープ チェーン オブジェクト内にあるため、アクセスコストが高くなります。以下に示すように:
したがって、この例では、ドキュメントをローカル変数に保存するだけでパフォーマンスが向上するため、プログラム内で with ステートメントを使用することは避けてください。
スコープ チェーンを変更するもう 1 つの点は、try-catch ステートメント内の catch ステートメントです。 try コード ブロックでエラーが発生すると、実行プロセスは catch ステートメントにジャンプし、その後、例外オブジェクトが可変オブジェクトにプッシュされ、スコープの先頭に配置されます。 catch ブロック内では、関数のすべてのローカル変数が 2 番目のスコープ チェーン オブジェクトに配置されます。サンプルコード:
try{
doSomething ();
}catch(ex){
alert(ex.message); //ここでスコープチェーンが変更されます
}
catch ステートメントが実行すると、スコープ チェーンは以前の状態に戻ります。 try-catch ステートメントはコードのデバッグや例外処理に非常に役立つため、完全に回避することはお勧めできません。コードを最適化することで、catch ステートメントのパフォーマンスへの影響を軽減できます。良いパターンは、エラー処理を関数に委任することです。例:
try{
doSomething();
}catch(ex){
handleError(ex); //プロセッサメソッドに委譲します
最適化されたコードでは、catch 句で実行されるコードは handleError メソッドだけです。この関数は例外オブジェクトをパラメータとして受け取るため、エラーをより柔軟かつ均一に処理できます。実行されるステートメントは 1 つだけであり、ローカル変数にはアクセスされないため、スコープ チェーンの一時的な変更はコードのパフォーマンスに影響しません。