こんにちは!私は Vishal Tiwari です。JavaScript の面接での難しい質問をいくつか紹介します。
console.log(typeof null); // Output?
出力: オブジェクト
説明: これは JavaScript のよく知られた癖です。 typeof 演算子は、null がオブジェクトではない場合でも、null に適用されると「object」を返します。この動作は JavaScript の実装方法に起因しており、下位互換性のために保持されています。
console.log(0.1 + 0.2 === 0.3); // Output?
出力: false
説明: JavaScript (および多くのプログラミング言語) での浮動小数点演算の仕組みにより、0.1 0.2 は 0.3 と正確には等しくありません。代わりに、結果は 0.30000000000000004 となり、比較では false が返されます。
const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; // What happens here? console.log(a[b]); // Output?
出力: 123
説明: 別のオブジェクトをキー (a[b]) として使用してオブジェクトにプロパティを設定しようとすると、JavaScript はオブジェクト b を文字列に変換します。その結果、「[object Object 】」。したがって、基本的にプロパティ "[object Object]" を 123 に設定することになり、a[b] をログに記録すると 123 が返されます。
const arr = [1, 2, 3]; arr[10] = 11; console.log(arr.length); // Output?
出力: 11
説明: 配列の現在の長さより大きいインデックス (arr[10] = 11 など) に値を割り当てると、JavaScript はその配列に「空のスロット」を作成します。ただし、配列の長さのプロパティは、最大のインデックスに 1 を加えたものを反映しており、この場合は 11 です。
let x = 1; let y = 2; const obj = { x: 10, y: 20, sum: function() { return this.x + this.y; } }; console.log(obj.sum()); // Output? console.log(obj.sum.call({ x: 100, y: 200 })); // Output? console.log(obj.sum.apply({ x: 1000, y: 2000 })); // Output?
出力:
説明:
console.log(1 + '1'); // Output? console.log(1 - '1'); // Output?
出力:
説明:
console.log(typeof null); // Output?
出力: 出力は foo が呼び出されるコンテキストによって異なりますが、グローバル コンテキストにある場合は、グローバル オブジェクト (ブラウザーのウィンドウまたは Node.js のグローバル) をログに記録します。
説明: アロー関数では、これは字句的に制限されており、周囲のコンテキストからの this 値を使用します。 foo がグローバル スコープで呼び出された場合、これはグローバル オブジェクトを参照します。
console.log(0.1 + 0.2 === 0.3); // Output?
出力:
説明: createCounter 関数は、独自のカウント変数を維持するクロージャを作成します。各メソッド (インクリメント、デクリメント、getCount) は同じカウント変数にアクセスして変更し、一貫した動作を提供します。
const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; // What happens here? console.log(a[b]); // Output?
出力: [99, 2, 3]
説明: JavaScript では、配列 (すべてのオブジェクトと同様) は参照型です。 b が a に代入されると、両方の変数はメモリ内の同じ配列を指します。したがって、b を変更すると a に影響します。
const arr = [1, 2, 3]; arr[10] = 11; console.log(arr.length); // Output?
出力: 3
説明: この例では、内部関数には独自の a 変数があり、外部関数の a 変数をシャドウします。 console.log(a) が inner 内で呼び出される場合、inner で定義された a である 3.
を参照します。let x = 1; let y = 2; const obj = { x: 10, y: 20, sum: function() { return this.x + this.y; } }; console.log(obj.sum()); // Output? console.log(obj.sum.call({ x: 100, y: 200 })); // Output? console.log(obj.sum.apply({ x: 1000, y: 2000 })); // Output?
出力: { a: 1, b: 3, c: 4 }
説明: Object.assign() メソッドは、すべての列挙可能なプロパティの値を 1 つ以上のソース オブジェクト (obj1 および obj2) からターゲット オブジェクト (空のオブジェクト {}) にコピーします。同じプロパティが複数のソース オブジェクトに存在する場合は、最後のプロパティが優先されます。したがって、obj2 の b: 3 は obj1 の b: 2 を上書きします。
console.log(1 + '1'); // Output? console.log(1 - '1'); // Output?
出力: 未定義
説明: 改行がある場合、JavaScript は return ステートメントの後に自動的にセミコロンを挿入します。したがって、これは return; として解釈され、未定義を返します。オブジェクトを返すには、return キーワードと同じ行に左中括弧 { を置く必要があります。
console.log(typeof null); // Output?
出力: 未定義
説明: 関数 foo 内の変数 x はホイストされますが、代入 var x = 2; になるまで初期化されません。したがって、console.log(x); の場合、を実行すると、ローカル x は宣言されていますが、まだ割り当てられていないため、unknown が出力されます。
console.log(0.1 + 0.2 === 0.3); // Output?
出力: 99
説明: a と b は両方ともメモリ内の同じ配列を参照します。 b[0] を変更すると、両方とも同じ配列を参照するため、a[0] も変更することになります。
const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; // What happens here? console.log(a[b]); // Output?
説明:
const arr = [1, 2, 3]; arr[10] = 11; console.log(arr.length); // Output?
出力: []
説明: 配列の長さプロパティを 0 に設定すると、実質的に配列がクリアされます。したがって、arr は空の配列になりました。
let x = 1; let y = 2; const obj = { x: 10, y: 20, sum: function() { return this.x + this.y; } }; console.log(obj.sum()); // Output? console.log(obj.sum.call({ x: 100, y: 200 })); // Output? console.log(obj.sum.apply({ x: 1000, y: 2000 })); // Output?
出力: 2
説明: 内部関数は呼び出されると、独自の変数 2 を持ちます。 innerFunc() を呼び出すと、内部のローカル変数 a を参照するため、2 が記録されます。
console.log(1 + '1'); // Output? console.log(1 - '1'); // Output?
出力: 3
説明: c メソッドは obj に対して呼び出されるため、メソッド内の this は obj を参照します。したがって、obj.a と obj.b の合計である 3 が出力されます。
const foo = () => { console.log(this); }; foo(); // Output?
説明:
console.log(typeof null); // Output?
出力: グローバル オブジェクト (または厳密モードでは未定義)
説明: 非厳密モードでは、グローバル コンテキストで呼び出される関数内の this の値はグローバル オブジェクト (つまり、ブラウザーのウィンドウまたは Node.js のグローバル) です。厳密モードでは、これは未定義になります。
console.log(0.1 + 0.2 === 0.3); // Output?
説明:
const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; // What happens here? console.log(a[b]); // Output?
出力: 3
説明: 内部関数では、a は外部関数で定義された変数を参照します。 inner が呼び出されると、a は 2 から 3 に増分され、ログに記録されます。
const arr = [1, 2, 3]; arr[10] = 11; console.log(arr.length); // Output?
出力: こんにちは、私の名前は未定義です
説明: コンテキストなしで (つまり、person のメソッドとしてではなく) 挨拶が呼び出された場合、これは person にバインドされません。非厳密モードでは、これはデフォルトでグローバル オブジェクトになり、名前がグローバル オブジェクトで定義されていないため、未定義のログが記録されます。
let x = 1; let y = 2; const obj = { x: 10, y: 20, sum: function() { return this.x + this.y; } }; console.log(obj.sum()); // Output? console.log(obj.sum.call({ x: 100, y: 200 })); // Output? console.log(obj.sum.apply({ x: 1000, y: 2000 })); // Output?
説明:
console.log(1 + '1'); // Output? console.log(1 - '1'); // Output?
説明: foo 関数は count 変数の周囲のクロージャを維持し、foo が呼び出されるたびにインクリメントされ、呼び出し間でその状態を保持します。
console.log(typeof null); // Output?
出力:
説明: a は、クロージャのため 2 番目の関数でアクセスできます。 b も、最初に定義されているようにアクセスできます。 c は秒に対してローカルであるため、3 つの変数はすべて正しくログに記録されます。
console.log(0.1 + 0.2 === 0.3); // Output?
出力: 3
説明: call メソッドは、このように newObj でインクリメントを呼び出すため、this.num は newObj.num を参照します。インクリメント操作により、newObj.num が 2 から 3 に変更されます。
const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; // What happens here? console.log(a[b]); // Output?
出力:
const arr = [1, 2, 3]; arr[10] = 11; console.log(arr.length); // Output?
説明: ホイストのため、setTimeout 関数はすべて同じ i 変数を参照しています。タイムアウトが実行されると、i はすでに 4 に増分されており、その結果、4 が 3 回ログに記録されます。
let x = 1; let y = 2; const obj = { x: 10, y: 20, sum: function() { return this.x + this.y; } }; console.log(obj.sum()); // Output? console.log(obj.sum.call({ x: 100, y: 200 })); // Output? console.log(obj.sum.apply({ x: 1000, y: 2000 })); // Output?
説明: マップ関数は、各項目に適用された変換に基づいて新しい配列を作成します。元の配列は変更されませんが、newArray は増分を反映します。
console.log(1 + '1'); // Output? console.log(1 - '1'); // Output?
出力: 出力は foo が呼び出されるコンテキストによって異なりますが、グローバル コンテキストにある場合は、グローバル オブジェクト (ブラウザーのウィンドウまたは Node.js のグローバル) をログに記録します。
説明: アロー関数では、これは字句的に制限されており、周囲のコンテキストからの this 値を使用します。 foo がグローバル スコープで呼び出された場合、これはグローバル オブジェクトを参照します。
const foo = () => { console.log(this); }; foo(); // Output?
出力: 42
説明: 内部関数はアロー関数であり、これをメソッド関数のコンテキストに字句的にバインドします。したがって、this.value は obj.value、つまり 42.
を参照します。function createCounter() { let count = 0; return { increment: function() { count++; return count; }, decrement: function() { count--; return count; }, getCount: function() { return count; } }; } const counter = createCounter(); console.log(counter.increment()); // Output? console.log(counter.increment()); // Output? console.log(counter.getCount()); // Output? console.log(counter.decrement()); // Output? console.log(counter.getCount()); // Output?
出力: ReferenceError
説明: 変数 x は myFunction 内でホイストされます。これは、変数 x が関数スコープ内に存在しますが、console.log(x) の後まで初期化されないことを意味します。 x 変数は宣言前にアクセスされるため、ReferenceError が発生します。
console.log(typeof null); // Output?
出力: こんにちは、未定義です
説明: 明示的なコンテキストなしでgreetが呼び出された場合、これはobjを参照しないため、this.nameは未定義です。
console.log(0.1 + 0.2 === 0.3); // Output?
出力: 数値
説明: JavaScript では、NaN (Not-a-Number) は数値型とみなされ、typeof NaN は「数値」を返します。
const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; // What happens here? console.log(a[b]); // Output?
出力: [1, 2, 3, 4]
説明: a と b は両方ともメモリ内の同じ配列を参照します。 4 を b に押し込むと、a にも影響します。
以上がトップの挑戦的で最も難しいJavaScript技術面接の質問とその解決策。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。