ホームページ >ウェブフロントエンド >jsチュートリアル >JS の概念に関する質問の概要と回答
今回はJSの概念質問の概要とQ&Aをお届けします。JSの概念質問を使用する際の注意事項は何ですか?実際の事例を見てみましょう。
Q: JavaScript における継承とプロトタイプチェーンについて説明し、例を挙げてください。
JavaScript はプロトタイプベースのオブジェクト指向言語であり、従来のクラスベースの継承システムを持っていません。
JS では、各オブジェクトは内部的にプロトタイプと呼ばれるオブジェクトを参照し、このプロトタイプ オブジェクト自体も独自のプロトタイプ オブジェクトを参照します。これによりプロトタイプ参照チェーンが形成され、その終端はプロトタイプとして null を持つオブジェクトになります。 JS は、プロトタイプ チェーンを介して継承を実装します。オブジェクトがそれ自体に属さないプロパティを参照する場合、参照されるプロパティが見つかるまで (またはチェーンの最後で直接見つかるまで、つまりプロパティが見つかるまで) プロトタイプ チェーンが走査されます。定義ではありません)。
簡単な例:
function Animal() { this.eatsVeggies = true; this.eatsMeat = false; }function Herbivore() {} Herbivore.prototype = new Animal();function Carnivore() { this.eatsMeat = true; } Carnivore.prototype = new Animal();var rabbit = new Herbivore();var bear = new Carnivore();console.log(rabbit.eatsMeat); // logs "false"console.log(bear.eatsMeat); // logs "true"
Q: 次のコード スニペットでは、アラートは何を表示しますか?あなたの答えを説明してください。
var foo = new Object();var bar = new Object();var map = new Object(); map[foo] = "foo"; map[bar] = "bar"; alert(map[foo]); // what will this display??
ここでアラート バーがポップアップします。JS オブジェクトは本質的にキーと値のペアのハッシュ テーブルであり、キーは常に 文字列 です。実際、文字列以外のオブジェクトがキーとして使用される場合、JS はそれを暗黙的に文字列に変換し、その値をキーとして使用します。
そのため、上記のコードのマップ オブジェクトが foo オブジェクトをキーとして使用すると、自動的に foo オブジェクトの toString() メソッドが呼び出され、そのデフォルトの実装がここで呼び出されます。文字列「[object Object]」が取得されます。次に、上記のコードを見てください。説明は次のとおりです:
var foo = new Object(); var bar = new Object(); var map = new Object(); map[foo] = "foo"; // --> map["[Object object]"] = "foo"; map[bar] = "bar"; // --> map["[Object object]"] = "bar"; // NOTE: second mapping REPLACES first mapping! alert(map[foo]); // --> alert(map["[Object object]"]); // and since map["[Object object]"] = "bar", // this will alert "bar", not "foo"!! // SURPRISE! ;-)
Q: JavaScript のクロージャについて説明してください。閉鎖とは何ですか?それらにはどのようなユニークな特性があるのでしょうか?どのように、そしてなぜそれらを使用しますか?例を挙げてください。
クロージャは、クロージャの作成時にスコープ内にあるすべての変数または他の関数を含む関数です。 JavaScript では、クロージャは「内部関数」の形式で実装されます。これは、別の関数の本体内で定義される関数です。以下に簡単な例を示します:
(function outerFunc(outerArg) { var outerVar = 3; (function middleFunc(middleArg) { var middleVar = 4; (function innerFunc(innerArg) { var innerVar = 5; // EXAMPLE OF SCOPE IN CLOSURE: // Variables from innerFunc, middleFunc, and outerFunc, // as well as the global namespace, are ALL in scope here. console.log("outerArg="+outerArg+ " middleArg="+middleArg+ " innerArg="+innerArg+"\n"+ " outerVar="+outerVar+ " middleVar="+middleVar+ " innerVar="+innerVar); // --------------- THIS WILL LOG: --------------- // outerArg=123 middleArg=456 innerArg=789 // outerVar=3 middleVar=4 innerVar=5 })(789); })(456); })(123);
クロージャの重要な特徴は、外部関数が戻った後でも内部関数が外部関数の変数にアクセスできることです。これは、JavaScript では、関数が実行されるときに、関数の作成時に有効だったスコープが引き続き使用されるためです。
ただし、内部関数が (作成時ではなく) 呼び出されたときに外部関数の変数の値にアクセスすると、混乱が生じる可能性があります。候補者がこのニュアンスを理解しているかどうかをテストするには、次のコード スニペットを使用します。これにより、動的に 5 つのボタンが作成され、ユーザーが 3 番目のボタンをクリックしたときに何が表示されるかを候補者に尋ねます:
function addButtons(numButtons) { for (var i = 0; i < numButtons; i++) { var button = document.createElement('input'); button.type = 'button'; button.value = 'Button ' + (i + 1); button.onclick = function() { alert('Button ' + (i + 1) + ' clicked'); }; document.body.appendChild(button); document.body.appendChild(document.createElement('br')); } }window.onload = function() { addButtons(5); };
多くの人が誤解しています。ユーザーが 3 番目のボタンをクリックすると、「ボタン 3 がクリックされました」と表示されます。実際、上記のコードには (クロージャの誤解に基づく) バグが含まれており、ユーザーが 5 つのボタンのいずれかをクリックすると、「ボタン 6 がクリックされました」と表示されます。これは、onclick メソッドが (任意のボタンに対して) 呼び出されるまでに、for ループが完了し、変数 i の値がすでに 5 になっているためです。
次に、予想される動作 (つまり、ボタン n をクリックすると「ボタン n がクリックされました」と表示される) が得られるように、上記のコードのエラーを修正する方法を候補者に尋ねることができます。受験者が正しい答えを出せた場合は、以下に示すように、クロージャの正しい使い方を知っていることになります:
function addButtons(numButtons) { for (var i = 0; i < numButtons; i++) { var button = document.createElement('input'); button.type = 'button'; button.value = 'Button ' + (i + 1); // HERE'S THE FIX: // Employ the Immediately-Invoked Function Expression (IIFE) // pattern to achieve the desired behavior: button.onclick = function(buttonIndex) { return function() { alert('Button ' + (buttonIndex + 1) + ' clicked'); }; }(i); document.body.appendChild(button); document.body.appendChild(document.createElement('br')); } }window.onload = function() { addButtons(5); };
この記事の事例を読んだ後は、その方法を習得したと思います。さらに興味深い情報については、注目してください。 PHP 中国語 Web サイトの他の関連記事へ!
推奨読書:
以上がJS の概念に関する質問の概要と回答の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。