Skip to content

Latest commit

 

History

History
2826 lines (1867 loc) · 83.2 KB

README-ja_JA.md

File metadata and controls

2826 lines (1867 loc) · 83.2 KB

JavaScript (高度な) 問題集

私は毎日、JavaScriptに関する選択問題を Instagramに投稿していますが、ここにも投稿します。

初級から上級まで: JavaScriptの知識のテストを行ったり、知識を少し深めたり、コーディング面接の準備をしてください。:muscle: :rocket: 私はこのレポを毎週新しい質問で更新します。Last update: June 29th

答えは質問の下の折りたたまれたセクションにあります、クリックすればそれを広げられます。幸運を祈ります。:heart:

利用可能な言語リスト:


1. 何が出力されるでしょうか?
function sayHi() {
  console.log(name);
  console.log(age);
  var name = "Lydia";
  let age = 21;
}

sayHi();
  • A: Lydiaundefined
  • B: LydiaReferenceError
  • C: ReferenceError21
  • D: undefinedReferenceError
答え

答え: D

関数内で、まず varキーワードを使って name変数を宣言します。これは、変数が定義されている行に実際に到達するまで、変数がデフォルト値の undefinedで初期化される(作成時にメモリ空間が設定される)ことを意味します。

name変数をログ出力を実行している行では、まだ変数を定義していませんので、undefinedの値を保持しています。

letキーワード(またはconst)を持つ変数は持ち上げられますが、 varとは異なり、初期化されません。それらを宣言(初期化)する行の前にはアクセスできません。これは"temporal dead zone"と呼ばれます。

宣言される前に変数にアクセスしようとすると、JavaScriptは ReferenceErrorを投げます。


2. 何が出力されるでしょうか?
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}
  • A: 0 1 20 1 2
  • B: 0 1 23 3 3
  • C: 3 3 30 1 2
答え

答え: C

JavaScriptのイベントキューのため、setTimeoutコールバック関数はループが実行された後に呼び出されます。最初のループの変数 ivarキーワードを使って宣言されているので、この値はグローバル変数となります。ループの間、単項演算子 ++を使用して、毎回 iの値を1ずつインクリメントしました。 最初の例では setTimeoutコールバック関数が呼び出されるまでにi3となりました。

2番目のループでは、変数 iletキーワードを使って宣言されました。 let(またはconst)キーワードで宣言された変数はブロックスコープです(ブロックは {}の間のものです)。それぞれの繰り返しの間、 iは新しい値を持ち、それぞれの値はループの内側にあります。


3. 何が出力されるでしょうか?
const shape = {
  radius: 10,
  diameter() {
    return this.radius * 2;
  },
  perimeter: () => 2 * Math.PI * this.radius
};

shape.diameter();
shape.perimeter();
  • A: 2062.83185307179586
  • B: 20NaN
  • C: 2063
  • D: NaN63
答え

答え: B

diameterの値は正則関数であり、perimeterの値はアロー関数です。

アロー関数では、thisキーワードは通常の関数とは異なり、現在の周囲の範囲を参照します。これは、perimeter関数を呼ぶと、shapeオブジェクトではなく、その周囲の範囲(例えば window)を参照することを意味します。

そのオブジェクトにはradiusという値はなく、undefinedを返します。


4. 何が出力されるでしょうか?
+true;
!"Lydia";
  • A: 1false
  • B: falseNaN
  • C: falsefalse
答え

答え: A

単項プラスは、オペランドを数値に変換しようとします。true1false0です

文字列「Lydia」は truthy valueです。ここで求めているのは、「このtruthy valueは、falsyなのか」ということです。これは falseを返します。


5. 正解はどれでしょう?
const bird = {
  size: "small"
};

const mouse = {
  name: "Mickey",
  small: true
};
  • A: mouse.bird.size is not valid
  • B: mouse[bird.size] is not valid
  • C: mouse[bird["size"]] is not valid
  • D: これらすべて有効です
答え

答え: A

JavaScriptでは、すべてのオブジェクトキーは文字列です(Symbolでない限り)。たとえそれを文字列として入力していなくても、それらは常にフードの下で文字列に変換されます。

JavaScriptは、ステートメントを解釈(または、ボックス解除)します。大括弧表記を使用すると、最初の左大括弧 [を見て、右大括弧 ]が見つかるまで進みます。その時だけ、そのステートメントを評価します。

mouse [bird.size]: まず最初に、bird.sizeが評価されます。これは文字列の "small"となります。 mouse["small"]は、trueを返します。

しかし、ドット表記では、これは起こりません。 mousebirdと呼ばれるキーを持っていません。 つまりmouse.birdundefinedとなります。

また、ドット表記を使って sizeを求めます: mouse.bird.size。 mouse.birdは未定義なので、実際にはundefined.sizeを要求しています。これは有効ではないので、Cannot read property "size" of undefinedような、エラーをスローします。



6. 何が出力されるでしょうか?
let c = { greeting: "Hey!" };
let d;

d = c;
c.greeting = "Hello";
console.log(d.greeting);
  • A: Hello
  • B: Hey
  • C: undefined
  • D: ReferenceError
  • E: TypeError
答え

答え: A

JavaScriptでは、すべてのオブジェクトは互いに等しく設定すると参照によって相互作用します。

まず、変数cは、オブジェクトに対する値を保持します。その後、cオブジェクトに対して持っている値と同じ参照でdに代入します。

1つのオブジェクトを変更すると、それらすべてが変更されます。


7. 何が出力されるでしょうか?
let a = 3;
let b = new Number(3);
let c = 3;

console.log(a == b);
console.log(a === b);
console.log(b === c);
  • A: true false true
  • B: false false true
  • C: true false false
  • D: false true true
答え

答え: C

new Number()は、組み込み関数のコンストラクタです。数字のように見えますが、実際には数字ではありません。たくさんの追加機能があり、それはオブジェクトとなります。

==演算子を使うとき、同じ値を持っているかどうか? をチェックするだけとなります。それらは両方とも3の値を持っているので、それはtrueを返します。

しかし、===演算子を使う時は、値と型は同じであるべきです。 そうでないので: new Number()は数値ではなく、オブジェクトとなります。なので、両方ともfalseを返します。


8. 何が出力されるでしょうか?
class Chameleon {
  static colorChange(newColor) {
    this.newColor = newColor;
    return this.newColor;
  }

  constructor({ newColor = "green" } = {}) {
    this.newColor = newColor;
  }
}

const freddie = new Chameleon({ newColor: "purple" });
freddie.colorChange("orange");
  • A: orange
  • B: purple
  • C: green
  • D: TypeError
答え

答え: D

colorChange関数は静的です。静的メソッドは、それらが作成されたコンストラクタ上でのみ動作するように設計されており、どの子達にも受け継がれません。 freddieは子となりますので、この関数は受け継がれず、freddieインスタンスでは利用できません。

その結果、TypeErrorが投げられます。


9. 何が出力されるでしょうか?
let greeting;
greetign = {}; // Typo!
console.log(greetign);
  • A: {}
  • B: ReferenceError: greetign is not defined
  • C: undefined
答え

答え: A

グローバルオブジェクトに、空のオブジェクトを作成したばかりなので、オブジェクトはログ出力されます。greetinggreetignと誤って入力した場合、JSインタプリタは実際にこれを global.greetign = {}(またはブラウザの window.greetign = {})と見なします。

これを避けるために、"use strict"を使用する事ができます。これにより、変数を何かに設定する前に、変数宣言したことを確認できます。


10. これを行うと、どうなりますか?
function bark() {
  console.log("Woof!");
}

bark.animal = "dog";
  • A: 何も起こらない、これは全く問題ない!
  • B: SyntaxError. この方法で関数にプロパティを追加することはできません。
  • C: undefined
  • D: ReferenceError
答え

答え: A

関数はオブジェクトとなるので、これはJavaScriptで可能です。(プリミティブ型以外はすべてオブジェクトです。)

関数は特別な種類のオブジェクトです。自分で書いたコードは実際の機能ではありません。関数はプロパティを持つオブジェクトです。よって、このプロパティは呼び出し可能となります。


11. 何が出力されるでしょうか?
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

const member = new Person("Lydia", "Hallie");
Person.getFullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

console.log(member.getFullName());
  • A: TypeError
  • B: SyntaxError
  • C: Lydia Hallie
  • D: undefined undefined
答え

答え: A

通常のオブジェクトのようにコンストラクタにプロパティを追加することはできません。一度にすべてのオブジェクトに機能を追加したい場合は、代わりにプロトタイプを使用する必要があります。だからこの場合は、

Person.prototype.getFullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

で、member.getFullName()が、機能するはずです。これはなぜ有益なのでしょうか。例えば、このメソッドをコンストラクタ自体に追加したとします。すべてのPersonインスタンスがこのメソッドを必要としなかったのかもしれません。

その場合、多くのメモリスペースを浪費する事でしょう。なぜならそれらはまだその特性を持ち、それは各インスタンスのためにメモリスペースを消費するからです。

その代わりに、プロトタイプに追加するだけであれば、メモリ内の1箇所に配置するだけで、すべてのユーザーがアクセスできます。


12. 何が出力されるでしょうか?
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

const lydia = new Person("Lydia", "Hallie");
const sarah = Person("Sarah", "Smith");

console.log(lydia);
console.log(sarah);
  • A: Person {firstName: "Lydia", lastName: "Hallie"}undefined
  • B: Person {firstName: "Lydia", lastName: "Hallie"}Person {firstName: "Sarah", lastName: "Smith"}
  • C: Person {firstName: "Lydia", lastName: "Hallie"}{}
  • D:Person {firstName: "Lydia", lastName: "Hallie"}ReferenceError
答え

答え: A

sarahでは、newキーワードを使いませんでした。newを使用した場合、作成した新しい空のオブジェクトを参照します。しかし、newを追加しなければ、それはグローバルオブジェクトを参照することとなります。

this.firstName"Sarah"を代入、this.lastName"Smith"を代入したつもりでしたが、実際に行った事は、global.firstName = 'Sarah' と、global.lastName = 'Smith'を定義したのです。

sarah自体は undefinedのままです。


13. イベント伝播の3つの段階はどれですか?
  • A: Target > Capturing > Bubbling
  • B: Bubbling > Target > Capturing
  • C: Target > Bubbling > Capturing
  • D: Capturing > Target > Bubbling
答え

答え: D

captureフェーズの間、イベントは先祖の要素を通過してターゲットの要素になります。それからtarget要素に達した後、バブリングが開始されます。


14. すべてのオブジェクトはプロトタイプを持っています。
  • A: true
  • B: false
答え

答え: B

基本オブジェクトを除き、すべてのオブジェクトにプロトタイプがあります。ベースオブジェクトは.toStringのようないくつかのメソッドとプロパティにアクセスできます。

これが、組み込みのJavaScriptメソッドを使用できる理由です。このような方法はすべてプロトタイプで利用できます。

JavaScriptはそれをあなたのオブジェクト上で直接見つけることはできませんが、プロトタイプチェーンをたどり、見つけます。


15. 何が出力されるでしょうか?
function sum(a, b) {
  return a + b;
}

sum(1, "2");
  • A: NaN
  • B: TypeError
  • C: "12"
  • D: 3
答え

答え: C

JavaScriptは、動的に型付けされた言語です。: 特定の変数がどんな型であるかは指定しません。知らないうちに、値が自動的に別の型に変換されることがあります。この事をimplicit type coercionと呼ばれてます。 Coercionは、ある型から別の型に変換しています。

この例では、関数が意味を成して値を返すために、JavaScriptは数字の1を文字列に変換します。数値型(1)と 文字列型('2')の追加中は、数字は文字列として扱われます。

"Hello"+"World"のように文字列を連結することができるので、ここで起こっているのは"1"+"2"で、これは "12"を返します。


16. 何が出力されるでしょうか?
let number = 0;
console.log(number++);
console.log(++number);
console.log(number);
  • A: 1 1 2
  • B: 1 2 2
  • C: 0 2 2
  • D: 0 1 2
答え

答え: C

接尾辞 単項演算子 ++

1.値を返す(これは0を返す) 2.値を増やす(numberは現在1です)

接頭辞 単項演算子 ++

1.値を増やす(数値は2になります) 2.値を返す(これは2を返します)

これは0 2 2を返します。


17. 何が出力されるでしょうか?
function getPersonInfo(one, two, three) {
  console.log(one);
  console.log(two);
  console.log(three);
}

const person = "Lydia";
const age = 21;

getPersonInfo`${person} is ${age} years old`;
  • A: "Lydia" 21 ["", " is ", " years old"]
  • B: ["", " is ", " years old"] "Lydia" 21
  • C: "Lydia" ["", " is ", " years old"] 21
答え

答え: B

タグ付きテンプレートリテラルを使用する場合、最初の引数の値は常に文字列値の配列です。残りの引数は渡された式の値を取得します。


18. 何が出力されるでしょうか?
function checkAge(data) {
  if (data === { age: 18 }) {
    console.log("You are an adult!");
  } else if (data == { age: 18 }) {
    console.log("You are still an adult.");
  } else {
    console.log(`Hmm.. You don't have an age I guess`);
  }
}

checkAge({ age: 18 });
  • A: You are an adult!
  • B: You are still an adult.
  • C: Hmm.. You don't have an age I guess
答え

答え: C

等価性をテストするとき、プリミティブはそれらの値によって比較され、オブジェクトはそれらの参照によって比較されます。 JavaScriptは、オブジェクトがメモリ内の同じ場所への参照を持っているかどうかを確認します。

比較している2つのオブジェクトにはそれがありません。パラメータとして渡したオブジェクトが、等価性を確認するために使用したオブジェクトとは異なるメモリ内の場所を参照しています。

これが { age: 18 } === { age: 18 }と、{ age: 18 } == { age: 18 }の両方が、falseを返す理由です。


19. 何が出力されるでしょうか?
function getAge(...args) {
  console.log(typeof args);
}

getAge(21);
  • A: "number"
  • B: "array"
  • C: "object"
  • D: "NaN"
答え

答え: C

スプレッド演算子(... args.)は、引数付きの配列を返します。配列はオブジェクトなので、typeof argsは、"object"を返します。


20. 何が出力されるでしょうか?
function getAge() {
  "use strict";
  age = 21;
  console.log(age);
}

getAge();
  • A: 21
  • B: undefined
  • C: ReferenceError
  • D: TypeError
答え

答え: C

"use strict"を使うと、誤ってグローバル変数を宣言しないようにすることができます。変数ageを宣言したことは一度もありませんし、"use strict"を使っているので参照エラーになります。

"use strict"を使用しなかった場合は、プロパティageがグローバルオブジェクトに追加されたことになるので、それは機能します。


21. sumの値は何?
const sum = eval("10*10+5");
  • A: 105
  • B: "105"
  • C: TypeError
  • D: "10*10+5"
答え

答え: A

evalは文字列として渡されたコードを評価します。この場合のように式であれば、その式を評価します。表現は10 * 10 + 5です。これは105を返します。


22. cool_secretは、どのくらいの期間アクセス可能ですか?
sessionStorage.setItem("cool_secret", 123);
  • A: 永遠に、データが失われることはありません。
  • B: ユーザーがタブを閉じる時
  • C: ユーザーがタブだけでなくブラウザ全体を閉じる時。
  • D: ユーザーが自分のコンピュータをシャットダウンした時。
答え

答え: B

sessionStorageに格納されたデータは、タブを閉じた後に削除されます。

localStorageを使用した場合は、localStorage.clear()などが呼び出されない限り、データは永久に存在しているでしょう。


23. 何が出力されるでしょうか?
var num = 8;
var num = 10;

console.log(num);
  • A: 8
  • B: 10
  • C: SyntaxError
  • D: ReferenceError
答え

答え: B

varキーワードを使うと、同じ名前で複数の変数を宣言できます。変数は最新の値を保持します。

ブロックスコープのletconstでは、できません。


24. 何が出力されるでしょうか?
const obj = { 1: "a", 2: "b", 3: "c" };
const set = new Set([1, 2, 3, 4, 5]);

obj.hasOwnProperty("1");
obj.hasOwnProperty(1);
set.has("1");
set.has(1);
  • A: false true false true
  • B: false true true true
  • C: true true false true
  • D: true true true true
答え

答え: C

すべてのオブジェクトキー(Symbolsを除く)は、文字列として自分で入力しなくても、内部では文字列です。これが、obj.hasOwnProperty('1')も​​trueを返す理由です。

setではそうはいきません。上記のsetには'1' はありません: set.has('1')は、falseを返します。数値型1set.has(1)は、trueを返します。


25. 何が出力されるでしょうか?
const obj = { a: "one", b: "two", a: "three" };
console.log(obj);
  • A: { a: "one", b: "two" }
  • B: { b: "two", a: "three" }
  • C: { a: "three", b: "two" }
  • D: SyntaxError
答え

答え: C

同じ名前のキーが2つある場合、最初の位置にあるキーは置き換えられ、最後に指定された値になります。


26. JavaScriptのglobal execution contextは、2つを作成します。: それはグローバルオブジェクトと "this"キーワードです。
  • A: true
  • B: false
  • C: 場合によりけり
答え

答え: A

基本的なexecution contextは、グローバルな実行コンテキストです。それはあなたのコードの至る所でアクセス可能なものです。


27. 何が出力されるでしょうか?
for (let i = 1; i < 5; i++) {
  if (i === 3) continue;
  console.log(i);
}
  • A: 1 2
  • B: 1 2 3
  • C: 1 2 4
  • D: 1 3 4
答え

答え: C

continueステートメントは、ある条件がtrueを返すと、繰り返し処理をスキップします。


28. 何が出力されるでしょうか?
String.prototype.giveLydiaPizza = () => {
  return "Just give Lydia pizza already!";
};

const name = "Lydia";

name.giveLydiaPizza();
  • A: "Just give Lydia pizza already!"
  • B: TypeError: not a function
  • C: SyntaxError
  • D: undefined
答え

答え: A

Stringはプロパティを追加することができる組み込みコンストラクタです。プロトタイプにメソッドを追加しました。

プリミティブ文字列は、文字列プロトタイプ関数によって生成された文字列オブジェクトに自動的に変換されます。

つまり、すべての文字列(文字列オブジェクト)がそのメソッドにアクセスできます。


29. 何が出力されるでしょうか?
const a = {};
const b = { key: "b" };
const c = { key: "c" };

a[b] = 123;
a[c] = 456;

console.log(a[b]);
  • A: 123
  • B: 456
  • C: undefined
  • D: ReferenceError
答え

答え: B

オブジェクトキーは自動的に文字列に変換されます。オブジェクトaのキーとして、値123で設定しようとしています。

しかし、オブジェクトを文字列化すると、それは"[Object object]"​​になってしまいます。なので、ここで行っているのは、 a["Object object"] = 123です。

その後、同じことをもう一度試みています。cは暗黙のうちに文字列化している別のオブジェクトです。そのため、a["Object object"] = 456となります。

その後、a[b]でログ出力。実際にはa["Object object"]です。これを 456に設定しただけなので、456を返します。


30. 何が出力されるでしょうか?
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"));
const baz = () => console.log("Third");

bar();
foo();
baz();
  • A: First Second Third
  • B: First Third Second
  • C: Second First Third
  • D: Second Third First
答え

答え: B

setTimeout関数があり、それを最初に呼び出したのですが、それは最後にログ出力されました。

これは、ブラウザにはランタイムエンジンがあるだけでなく、WebAPIと呼ばれるものもあるからです。WebAPIは最初にsetTimeout関数を与えてくれます。例えばDOMです。

callbackがWebAPIにプッシュされた後、setTimeout関数自体(コールバックではありません!)がスタックからポップされます。

今、fooが呼び出され、"First"が、ログ出力されています。

fooがスタックからポップされ、bazが呼び出されます。"Third"が、ログ出力されます。

WebAPIは、準備が整ったときにスタックに、なにかを追加することはできません。代わりに、コールバック関数をqueueと呼ばれるものにプッシュします。

event loopが機能し始めるところです。 event loopはスタックとタスクキューを調べます。スタックが空の場合は、キューの最初のものを取り出し、それをスタックにプッシュします。

barが呼び出され、"Second"がログ出力され、スタックからポップされます。


31.ボタンをクリックしたときのevent.targetは何ですか?
<div onclick="console.log('first div')">
  <div onclick="console.log('second div')">
    <button onclick="console.log('button')">
      Click!
    </button>
  </div>
</div>
  • A: 外側 div
  • B: 内側 div
  • C: button
  • D: ネストしたすべての要素の配列
答え

答え: C

イベントを引き起こした最も深くネストした要素がイベントのターゲットとなります。event.stopPropagationでバブリングを止めることができます


32. p要素をクリックすると、ログ出力はどうなりますか。
<div onclick="console.log('div')">
  <p onclick="console.log('p')">
    Click here!
  </p>
</div>
  • A: p div
  • B: div p
  • C: p
  • D: div
答え

答え: A

pをクリックすると、pdivの2つのログが表示されます。イベント伝播中は、キャプチャ、ターゲット、バブリングの3つのフェーズがあります。

デフォルトでは、イベントハンドラはバブリング段階で実行されます(useCapturetrueに設定しない限り)。最も深くネストした要素から外側に向かって進みます。


33. 何が出力されるでしょうか?
const person = { name: "Lydia" };

function sayHi(age) {
  console.log(`${this.name} is ${age}`);
}

sayHi.call(person, 21);
sayHi.bind(person, 21);
  • A: undefined is 21 Lydia is 21
  • B: function function
  • C: Lydia is 21 Lydia is 21
  • D: Lydia is 21 function
答え

答え: D

両方とも、thisキーワードが参照したいオブジェクトを渡すことができます。しかし、.callもすぐに実行されます。

.bind.は関数のコピーを返しますが、コンテキストは束縛されています。すぐには実行されません。


34. 何が出力されるでしょうか?
function sayHi() {
  return (() => 0)();
}

typeof sayHi();
  • A: "object"
  • B: "number"
  • C: "function"
  • D: "undefined"
答え

答え: B

sayHi関数は、即時呼び出し関数式(IIFE)の戻り値を返します。この関数は0を返しました。それは"number"型です。

参考:7つの組み込み型しかありません: null, undefined, boolean, number, string, object, そしてsymbol。関数はオブジェクトなので、"function"型ではなく"object"型です。


35. これらの値のどれがfalsyですか?
0;
new Number(0);
("");
(" ");
new Boolean(false);
undefined;
  • A: 0, '', undefined
  • B: 0, new Number(0), '', new Boolean(false), undefined
  • C: 0, '', new Boolean(false), undefined
  • D: これらすべてfalsy
答え

答え: A

falsyの値は6つだけです。

  • undefined
  • null
  • NaN
  • 0
  • '' (empty string)
  • false

new Numberや、new Booleanのような関数コンストラクタはtruthyです。


36. 何が出力されるでしょうか?
console.log(typeof typeof 1);
  • A: "number"
  • B: "string"
  • C: "object"
  • D: "undefined"
答え

答え: B

typeof 1は、"number"を返します。

typeof "number"は、"string"を返します。


37. 何が出力されるでしょうか?
const numbers = [1, 2, 3];
numbers[10] = 11;
console.log(numbers);
  • A: [1, 2, 3, 7 x null, 11]
  • B: [1, 2, 3, 11]
  • C: [1, 2, 3, 7 x empty, 11]
  • D: SyntaxError
答え

答え: C

配列の長さを超える値を配列内の要素に設定すると、JavaScriptでは、"empty slots"と呼ばれるものを作成します。これらは実際には、undefinedの値を持ちますが、あなたは以下のようなものを見るでしょう

[1, 2, 3, 7 x empty, 11]

実行場所によって異なります(browser、nodeなどによって異なります)。


38. 何が出力されるでしょうか?
(() => {
  let x, y;
  try {
    throw new Error();
  } catch (x) {
    (x = 1), (y = 2);
    console.log(x);
  }
  console.log(x);
  console.log(y);
})();
  • A: 1 undefined 2
  • B: undefined undefined undefined
  • C: 1 1 2
  • D: 1 undefined undefined
答え

答え: A

catchブロックは引数xを受け取ります。これは引数を渡すときの変数と同じxではありません。この変数xはブロックスコープです。

後に、このブロックスコープ変数を1に設定し、変数yの値を設定します。ここで、ブロックスコープ変数xをログ出力します。これは1となります。

catchブロック以外では、xは未定義、yは2です。 catchブロックの外側でconsole.log(x)した場合は、undefinedを返し、y2を返します。


39. JavaScriptのすべてはどちらかです...
  • A: primitive か object
  • B: function か object
  • C: ひっかけ問題! objectsのみ
  • D: number か object
答え

答え: A

JavaScriptにはプリミティブ型とオブジェクトしかありません。

プリミティブ型は、boolean, null, undefined, bigint, number, string, そしてsymbolです。

プリミティブとオブジェクトを区別するのは、プリミティブにはプロパティもメソッドもないということです。

ただし、'foo'.toUpperCase()'FOO'と評価され、TypeErrorにはなりません。これは、文字列のようなプリミティブのプロパティやメソッドにアクセスしようとすると、JavaScriptがラッパークラスの1つ、すなわちStringを使ってオブジェクトを暗黙的にラップし、式が評価された後ラッパーを直ちに破棄するためです。

nullundefinedを除くすべてのプリミティブはこの振る舞いをします。


40. 何が出力されるでしょうか?
[[0, 1], [2, 3]].reduce(
  (acc, cur) => {
    return acc.concat(cur);
  },
  [1, 2]
);
  • A: [0, 1, 2, 3, 1, 2]
  • B: [6, 1, 2]
  • C: [1, 2, 0, 1, 2, 3]
  • D: [1, 2, 6]
答え

答え: C

[1,2]は初期値です。これが最初の値で、一番最初のaccの値です。最初の周回の間、acc[1,2]で、cur[0,1]です。それらを連結すると、結果として[1、2、0、1]となります。

そして、[1, 2, 0, 1]acc[2, 3]curを連結して[1, 2, 0, 1, 2, 3]を得ます


41. 何が出力されるでしょうか?
!!null;
!!"";
!!1;
  • A: false true false
  • B: false false true
  • C: false true true
  • D: true true false
答え

答え: B

nullはfalsyです。!nulltrueを返します。!truefalseを返します。

""はfalsyです。!""trueを返します。!truefalseを返します。

1はtruthyです。!1falseを返します。!falsetrueを返します。


42. setIntervalメソッドはブラウザに何を返しますか?
setInterval(() => console.log("Hi"), 1000);
  • A: ユニークid
  • B: 指定されたミリ秒数
  • C: 渡された関数
  • D: undefined
答え

答え: A

一意のIDを返します。このIDは clearInterval()関数で、その間隔をクリアするために使うことができます。


43. これは何を返しますか?
[..."Lydia"];
  • A: ["L", "y", "d", "i", "a"]
  • B: ["Lydia"]
  • C: [[], "Lydia"]
  • D: [["L", "y", "d", "i", "a"]]
答え

答え: A

文字列はイテラブルです。スプレッド演算子は、イテラブルのすべての文字を1つの要素にマッピングします。

44. 何が出力されるでしょうか?
function* generator(i) {
  yield i;
  yield i * 2;
}

const gen = generator(10);

console.log(gen.next().value);
console.log(gen.next().value);
  • A: [0, 10], [10, 20]
  • B: 20, 20
  • C: 10, 20
  • D: 0, 10 and 10, 20
答え

答え: C

通常の関数は、呼び出し後に途中で停止することはできません。ただし、ジェネレータ関数は途中で"停止"し、後で停止した場所から続行することができます。

ジェネレータ関数がyieldキーワードを見つけるたびに、その関数はその後に指定された値を返します。その場合のジェネレータ関数は、値を"返す"わけではないことに注意してください。値を生み出しています。

まず、i10を指定してジェネレータ関数を初期化します。次にnext()メソッドを使用してジェネレータ関数を呼び出します。

最初にジェネレータ関数を呼び出すと、i10になり、最初のyieldキーワードに遭遇します。そこからiの値が得られます。ジェネレータは"一時停止"され、10がログ出力されます。

それから、next()メソッドを使って関数を再度呼び出します。依然としてi10のまま、以前に停止したところから継続し始めます。

それから次のyieldキーワードに遭遇し、そこからi * 2の値が得られます。i10のままなので、10 * 2、つまり20を返します。なので、10、20が返る事になります。


45. これは何を返しますか?
const firstPromise = new Promise((res, rej) => {
  setTimeout(res, 500, "one");
});

const secondPromise = new Promise((res, rej) => {
  setTimeout(res, 100, "two");
});

Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
  • A: "one"
  • B: "two"
  • C: "two" "one"
  • D: "one" "two"
答え

答え: B

複数のプロミスをPromise.raceメソッドに渡した時、"resolves/rejects"は、"最初"のプロミスの"resolves/rejects"を行います。

setTimeoutメソッドには、タイマーを渡します: 最初のプロミスには500ms(firstPromise)、2番目のプロミスには100ms(secondPromise)。

これは、secondPromiseが最初に'two'の値で解決されることを意味します。res'two'の値を保持するようになり、ログ出力されます。


46. 何が出力されるでしょうか?
let person = { name: "Lydia" };
const members = [person];
person = null;

console.log(members);
  • A: null
  • B: [null]
  • C: [{}]
  • D: [{ name: "Lydia" }]
答え

答え: D

まず、nameプロパティを持つオブジェクトの値を使って、変数personを宣言します。

それから、membersという変数を宣言します。その配列の最初の要素に、変数personの値を代入します。オブジェクトは、互いをイコールで設定すると、「参照」によって相互作用します。

ある変数から別の変数への"参照"を代入すると、その参照の"コピー"が作成されます。 (それらは、"同じ参照"を持っていないことに注意してください!)

そして、変数personnullに設定します。

その要素はオブジェクトへの異なる(コピーされた)参照を持っているので、person変数の値を変更するだけで配列の最初の要素は変更されません。 membersの最初の要素はまだ元のオブジェクトへの参照を保持しています。

members配列をログ出力したとき、最初の要素はまだオブジェクトの値を保持しているので、それがログ出力されます。


47. 何が出力されるでしょうか?
const person = {
  name: "Lydia",
  age: 21
};

for (const item in person) {
  console.log(item);
}
  • A: { name: "Lydia" }, { age: 21 }
  • B: "name", "age"
  • C: "Lydia", 21
  • D: ["name", "Lydia"], ["age", 21]
答え

答え: B

この場合、for-inループを使うと、オブジェクトキーであるnameageの繰り返し処理できます。内部的には、オブジェクトキーは文字列です(シンボルではない場合)。

すべてのループで、itemの値は反復している現在のキーに設定されます。まず、itemnameが代入され、ログに出力されます。その後、itemageが代入され、ログに出力されます。


48. 何が出力されるでしょうか?
console.log(3 + 4 + "5");
  • A: "345"
  • B: "75"
  • C: 12
  • D: "12"
答え

答え: B

演算子結合性は、コンパイラーが式を評価する順序(左から右または右から左)となります。これは、すべての演算子が同じ優先順位を持つ場合にのみ発生します。演算子の種類は1つだけです: +。さらに、結合性は左から右です。

3 + 4が最初に評価されます。これは数字の7になります。

7 + '5'は、強制的に"75"になります。 JavaScriptでは、数字の7を文字列に変換します。質問15を参照してください。2つの文字列を演算子の+を使って連結することができます。よって、"7" + "5"は、"75"になります。


49. numの値は何ですか?
const num = parseInt("7*6", 10);
  • A: 42
  • B: "42"
  • C: 7
  • D: NaN
答え

答え: C

文字列の最初の数字だけが返されます。"基数"(解析する数値の種類を指定するための2番目の引数: 基数10, 16進数, 8進数, 2進数など)に基づいて、parseIntは文字列内の文字が有効かどうかをチェックします。基数の中で有効な数字ではない文字に出会うと、構文解析を停止して次の文字を無視します。

*は、有効な数字ではありません。"7"を、10進数の7に解析するだけです。そのままnumは7の値を保持します。


50. 何が出力されるでしょうか?
[1, 2, 3].map(num => {
  if (typeof num === "number") return;
  return num * 2;
});
  • A: []
  • B: [null, null, null]
  • C: [undefined, undefined, undefined]
  • D: [ 3 x empty ]
答え

答え: C

配列をマッピングするとき、numの値に代入されるのは、ループで渡ってくる要素となります。この場合、要素は数値なので、ifステートメント typeof num === "number"の条件はtrueを返します。 map関数は新しい配列を作成して関数から返された値を挿入します。

ただし、値は返されません。関数から値を返さないと、関数はundefinedを返します。配列内のすべての要素に対して関数ブロックが呼び出されるので、各要素に対してundefinedを返します。


51. 何が出力されるでしょうか?
function getInfo(member, year) {
  member.name = "Lydia";
  year = 1998;
}

const person = { name: "Sarah" };
const birthYear = "1997";

getInfo(person, birthYear);

console.log(person, birthYear);
  • A: { name: "Lydia" }, "1997"
  • B: { name: "Sarah" }, "1998"
  • C: { name: "Lydia" }, "1998"
  • D: { name: "Sarah" }, "1997"
答え

答え: A

値がオブジェクトでない限り、引数は"値"によって渡され、その後、"参照"によって渡されます。 birthYearはオブジェクトではなく文字列なので、値で渡されます。引数を値で渡すと、その値の"コピー"が作成されます(質問46を参照)。

変数birthYearは、値"1997"への参照を持ちます。引数yearは、値"1997"も参照していますが、それはbirthYearが参照しているのと同じ値ではありません。year"1998"を代入することによってyearの値を更新したとしても、yearの値を更新するだけです。birthYearはまだ"1997"となります。

personの値はオブジェクトです。引数memberは"同じ"オブジェクトへの(コピーされた)参照を持ちます。

memberが参照を持つオブジェクトのプロパティを変更すると、personの値も変更されます。これらは両方とも同じオブジェクトへの参照を持つからです。personnameプロパティは、値の"Lydia"となりました。


52. 何が出力されるでしょうか?
function greeting() {
  throw "Hello world!";
}

function sayHi() {
  try {
    const data = greeting();
    console.log("It worked!", data);
  } catch (e) {
    console.log("Oh no an error!", e);
  }
}

sayHi();
  • A: "It worked! Hello world!"
  • B: "Oh no an error: undefined
  • C: SyntaxError: can only throw Error objects
  • D: "Oh no an error: Hello world!
答え

答え: D

throwステートメントを使って、カスタムエラーを作ることができます。このステートメントで、あなたは例外を投げることができます。例外は、string, number, boolean, objectのいずれかとなります。上記の場合だと、例外は文字列'Hello world'となります。

catchステートメントを使って、tryブロックで例外が投げられた場合にどうするかを指定できます。例外がスローされます: 文字列'Hello world'は、eに代入されます。その結果'Oh an error: Hello world'となります。


53. 何が出力されるでしょうか?
function Car() {
  this.make = "Lamborghini";
  return { make: "Maserati" };
}

const myCar = new Car();
console.log(myCar.make);
  • A: "Lamborghini"
  • B: "Maserati"
  • C: ReferenceError
  • D: TypeError
答え

答え: B

プロパティを返すと、そのプロパティの値は、コンストラクタ関数で設定された値ではなく、"戻り値"となります。 "Maserati"という文字列を返すので、myCar.make"Maserati"となります。


54. 何が出力されるでしょうか?
(() => {
  let x = (y = 10);
})();

console.log(typeof x);
console.log(typeof y);
  • A: "undefined", "number"
  • B: "number", "number"
  • C: "object", "number"
  • D: "number", "undefined"
答え

答え: A

let x = y = 10; is actually shorthand for:

y = 10;
let x = y;

y10を代入すると、実際にはグローバルオブジェクトにプロパティyが追加されます(ブラウザではwindow、nodeではglobal)。ブラウザでは、window.y10となりました。

それから、変数x10である値yで宣言します。letキーワードで宣言された変数は"ブロックスコープ"となり、宣言されたブロック内でのみ定義されます。この場合は即時関数(IIFE)となります。

typeof演算子使用時、オペランドxは定義されていません: 宣言されているブロックの外側でxにアクセスしようとしています。これはxが定義されていないことを意味します。

値が割り当てられていない、または宣言されていない値は"undefined"型となります。なのでconsole.log(typeof x)"undefined"を返します。

yに関しては、y10を代入するときにグローバル変数yを作成しました。この値は、コード内のどこからでもアクセスできます。yが定義されていて、"number"型の値を保持します。よってconsole.log(typeof y)"number"を返します。

55. 何が出力されるでしょうか?
class Dog {
  constructor(name) {
    this.name = name;
  }
}

Dog.prototype.bark = function() {
  console.log(`Woof I am ${this.name}`);
};

const pet = new Dog("Mara");

pet.bark();

delete Dog.prototype.bark;

pet.bark();
  • A: "Woof I am Mara", TypeError
  • B: "Woof I am Mara","Woof I am Mara"
  • C: "Woof I am Mara", undefined
  • D: TypeError, TypeError
答え

答え: A

プロトタイプでも、deleteキーワードを使ってオブジェクトからプロパティを削除できます。プロトタイプのプロパティを削除すると、プロトタイプチェーンでは使用できなくなります。

この場合、bark関数は delete Dog.prototype.barkの後のプロトタイプでは、もう利用できず、それでもアクセスし、関数ではない何かを呼び出そうとすると、TypeErrorがスローされます。

関数ではない何かを呼び出そうとすると、pet.barkundefinedなので、TypeErrorがスローされ、TypeError: pet.bark is not a functionとなります。


56. 何が出力されるでしょうか?
const set = new Set([1, 1, 2, 3, 4]);

console.log(set);
  • A: [1, 1, 2, 3, 4]
  • B: [1, 2, 3, 4]
  • C: {1, 1, 2, 3, 4}
  • D: {1, 2, 3, 4}
答え

答え: D

Setオブジェクトは unique の値の集合です: 値は集合の中で一度だけ現れることができます

1が重複したイテラブル[1、1、2、3、4]を渡しました。セット内に同じ値を2つ持つことはできないので、そのうちの1つが削除され{1、2、3、4}となります。


57. 何が出力されるでしょうか?
// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter";

myCounter += 1;

console.log(myCounter);
  • A: 10
  • B: 11
  • C: Error
  • D: NaN
答え

答え: C

インポートされたモジュールは読み取り専用です。: インポートされたモジュールを変更することはできません。エクスポートするモジュールだけがその値を変更できます。

myCounterの値を増やそうとすると、error: myCounter is read-only and cannot be modified. と、エラーがスローされます。


58. 何が出力されるでしょうか?
const name = "Lydia";
age = 21;

console.log(delete name);
console.log(delete age);
  • A: false, true
  • B: "Lydia", 21
  • C: true, true
  • D: undefined, undefined
答え

答え: A

delete演算子は、ブール値を返します: 正常に削除された場合はtrue、それ以外の場合はfalseを返します。var, constまたはletキーワードで宣言された変数はdelete演算子を使って削除することはできません。

name変数はconstキーワードで宣言されているので、削除は成功しません: falseが返されます。

age21に設定すると、実際にはグローバルオブジェクトにageというプロパティを追加されました。グローバルオブジェクトからもプロパティを削除することができますので、delete agetrueを返します。


59. 何が出力されるでしょうか?
const numbers = [1, 2, 3, 4, 5];
const [y] = numbers;

console.log(y);
  • A: [[1, 2, 3, 4, 5]]
  • B: [1, 2, 3, 4, 5]
  • C: 1
  • D: [1]
答え

答え: C

配列から値を取り出したり、オブジェクトからプロパティを分解して取り出すことができます。 example:

[a, b] = [1, 2];

aの値は1となり、bの値は2となる。実際に問題で行った事は、

[y] = [1, 2, 3, 4, 5];

yの値が配列の最初の値、つまり1に等しいことを意味します。yをログ出力すると、1が返されます。


60. 何が出力されるでしょうか?
const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user };

console.log(admin);
  • A: { admin: true, user: { name: "Lydia", age: 21 } }
  • B: { admin: true, name: "Lydia", age: 21 }
  • C: { admin: true, user: ["Lydia", 21] }
  • D: { admin: true }
答え

答え: B

スプレッド演算子...を使ってオブジェクトを結合することができます。あるオブジェクトのキーと値のペアのコピーを作成し、それらを別のオブジェクトに追加することができます。

上記の場合だと、userオブジェクトのコピーを作成し、それらをadminオブジェクトに追加します。adminオブジェクトはコピーされたキーと値のペアを含み、その結果{admin:true、name: "Lydia"、age:21}となります。


61. 何が出力されるでしょうか?
const person = { name: "Lydia" };

Object.defineProperty(person, "age", { value: 21 });

console.log(person);
console.log(Object.keys(person));
  • A: { name: "Lydia", age: 21 }, ["name", "age"]
  • B: { name: "Lydia", age: 21 }, ["name"]
  • C: { name: "Lydia"}, ["name", "age"]
  • D: { name: "Lydia"}, ["age"]
答え

答え: B

definePropertyメソッドを使うと、オブジェクトに新しいプロパティを追加したり、既存のプロパティを修正することができます。 definePropertyメソッドを使ってオブジェクトにプロパティを追加すると、それらはデフォルトでは 列挙できません

Object.keysメソッドはオブジェクトから全ての enumerable (列挙可能)なプロパティ名を返します。上記の場合は"name"だけとなります。

definePropertyメソッドを使って追加されたプロパティはデフォルトでは不変となります。 この動作はwritable, configurable, enumerableプロパティを使って上書きすることができます。このように、definePropertyメソッドは、オブジェクトに追加しようとしているプロパティをもっと細かく制御できます。


62. 何が出力されるでしょうか?
const settings = {
  username: "lydiahallie",
  level: 19,
  health: 90
};

const data = JSON.stringify(settings, ["level", "health"]);
console.log(data);
  • A: "{"level":19, "health":90}"
  • B: "{"username": "lydiahallie"}"
  • C: "["level", "health"]"
  • D: "{"username": "lydiahallie", "level":19, "health":90}"
答え

答え: A

JSON.stringifyの2番目の引数は replacer です。replacerは、関数または配列のいずれかにすることができ、値を文字列化する対象とその方法を制御できます。

replacerが array の場合、名前が配列に含まれるプロパティのみがJSON文字列に追加されます。上記の場合、"level""health"という名前のプロパティだけが含まれ、"username"は除外されます。data"{" level ":19、" health ":90}"となります。

replacerが function の場合、この関数は文字列化しているオブジェクト内のすべてのプロパティに対して呼び出されます。この関数から返される値は、JSON文字列に追加されたときのプロパティの値になり、値がundefinedの場合、このプロパティはJSON文字列から除外されます。


63. 何が出力されるでしょうか?
let num = 10;

const increaseNumber = () => num++;
const increasePassedNumber = number => number++;

const num1 = increaseNumber();
const num2 = increasePassedNumber(num1);

console.log(num1);
console.log(num2);
  • A: 10, 10
  • B: 10, 11
  • C: 11, 11
  • D: 11, 12
答え

答え: A

単項演算子++はオペランドの値を 最初に返しその後に インクリメント します。num1の値は10となります。 なぜならincrementNumber関数は、最初にnumの値10を返し、その後にnumの値をインクリメントするだけです。

num1increPassedNumberに渡したので、num210です。number10num1の値です。繰り返しますが、単項演算子++は、オペランドの値を 最初に返しその後に インクリメント します。したがって、num210となります。


64. 何が出力されるでしょうか?
const value = { number: 10 };

const multiply = (x = { ...value }) => {
  console.log((x.number *= 2));
};

multiply();
multiply();
multiply(value);
multiply(value);
  • A: 20, 40, 80, 160
  • B: 20, 40, 20, 40
  • C: 20, 20, 20, 40
  • D: NaN, NaN, 20, 40
答え

答え: C

ES6では、パラメータをデフォルト値で初期化できます。値が関数に渡されていない場合やパラメータの値が "undefined"の場合、パラメータの値はデフォルト値になります。上記の場合、valueオブジェクトのプロパティを新しいオブジェクトに分割代入されるので、xのデフォルト値は{number:10}になります。

デフォルトの引数は、呼び出し時 に評価されます。関数を呼び出すたびに、新しい オブジェクトが作成されます。

最初に値を渡さずに2回、multiply関数を呼び出します: xのデフォルト値は {number:10}となり、その数の乗算された値、つまり 20を出力します。

3回目のmultiplyを呼び出すとき、引数を渡します: valueというオブジェクトです。

*=演算子はx.number = x.number * 2の省略形となります: x.numberの値は乗算した値に修正され、20を出力します。

4回目は、valueオブジェクトをもう一度渡します。x.numberは以前は20に修正されているので、x.number *= 240を出力します。


65. 何が出力されるでしょうか?
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));
  • A: 1 2 and 3 3 and 6 4
  • B: 1 2 and 2 3 and 3 4
  • C: 1 undefined and 2 undefined and 3 undefined and 4 undefined
  • D: 1 2 and undefined 3 and undefined 4
答え

答え: D

reduceメソッドが受け取る最初の引数は アキュムレータ となります。この場合はxです。 2番目の引数は、現在の値 yです。 reduceメソッドでは、配列内のすべての要素に対してコールバック関数を実行します。これにより、最終的に1つの値が得られます。

上記の例では、値を返していません。単にアキュムレータの値と現在の値を記録しています。

アキュムレータの値は、以前に返されたコールバック関数の値と同じです。オプションのinitialValue引数をreduceメソッドに渡さないと、アキュムレータは最初の呼び出しの最初の要素に等しくなります。

最初の呼び出しでは、アキュムレータ(x)は1であり、現在値(y)は2となります。コールバック関数からは戻らないので、アキュムレータと現在の値を出力します: 12が出力されます。

関数から値を返さなければ、undefinedを返します。次の呼び出しでは、アキュムレータはundefinedで、現在の値は3です。undefined3が出力されます。

4回目の呼び出しでも、コールバック関数からは戻りません。アキュムレータもまたundefinedであり、現在の値は4となり、undefined4が出力されます。


66. どのコンストラクタを使えば Dog classを継承できるでしょうか?
class Dog {
  constructor(name) {
    this.name = name;
  }
};

class Labrador extends Dog {
  // 1 
  constructor(name, size) {
    this.size = size;
  }
  // 2
  constructor(name, size) {
    super(name);
    this.size = size;
  }
  // 3
  constructor(size) {
    super(name);
    this.size = size;
  }
  // 4 
  constructor(name, size) {
    this.name = name;
    this.size = size;
  }

};
  • A: 1
  • B: 2
  • C: 3
  • D: 4
答え

答え: B

派生クラスでは、superを呼び出す前に、thisキーワードにアクセスすることはできません。そうしようとすると、ReferenceErrorがスローされます: 1と4は参照エラーをスローします。

superキーワードを使って、与えられた引数で、その親クラスのコンストラクタを呼び出します。親のコンストラクタはname引数を受け取るので、namesuperに渡す必要があります。

Labradorクラスは2つの引数、Dogを拡張するためのnameと、Labradorクラスの追加のプロパティとしてのsizeを受け取ります。

両方ともLabradorのコンストラクタ関数に渡す必要があります。これはコンストラクタ2を使って正しく実行されます。


67. 何が出力されるでしょうか?
// index.js
console.log('running index.js');
import { sum } from './sum.js';
console.log(sum(1, 2));

// sum.js
console.log('running sum.js');
export const sum = (a, b) => a + b;
  • A: running index.js, running sum.js, 3
  • B: running sum.js, running index.js, 3
  • C: running sum.js, 3, running index.js
  • D: running index.js, undefined, running sum.js
答え

答え: B

importキーワードを使うと、全てのインポートされたモジュールは 事前解析 されます。これは、インポートされたモジュールが 最初 に実行され、その後 モジュールをインポートしたファイル内のコードが実行されることを意味します。

これはCommonJSのrequire()importの違いです。require()を使うと、コードが実行されている間に依存関係をオンデマンドでロードすることができます。

importの代わりにrequireを使用したとしたら、running index.js, running sum.js, 3が出力されているはずです。


68. 何が出力されるでしょうか?
console.log(Number(2) === Number(2))
console.log(Boolean(false) === Boolean(false))
console.log(Symbol('foo') === Symbol('foo'))
  • A: true, true, false
  • B: false, true, false
  • C: true, false, true
  • D: true, true, true
答え

答え: A

すべてのシンボルは完全にユニークです。シンボルに渡される引数の目的は、シンボルに説明を与えることです。Symbolの値は渡された引数に依存しません。

等価性をテストしているので、2つのまったく新しいシンボルを作成します: 最初のSymbol('foo')と、2番目のSymbol('foo')です。これら2つの値は一意であり、互いに等しくはありません、なのでSymbol('foo') === Symbol('foo')falseを返します。


69. 何が出力されるでしょうか?
const name = "Lydia Hallie"
console.log(name.padStart(13))
console.log(name.padStart(2))
  • A: "Lydia Hallie", "Lydia Hallie"
  • B: " Lydia Hallie", " Lydia Hallie" ("[13x whitespace]Lydia Hallie", "[2x whitespace]Lydia Hallie")
  • C: " Lydia Hallie", "Lydia Hallie" ("[1x whitespace]Lydia Hallie", "Lydia Hallie")
  • D: "Lydia Hallie", "Lyd",
答え

答え: C

padStartメソッドを使うと、文字列の先頭にパディングを追加できます。このメソッドに渡される値は、パディングとともに文字列の長さの 合計 です。文字列"Lydia Hallie"の長さは12です。 name.padStart(13)は、12 + 1が13であるため、文字列の先頭に1スペースを挿入されます。

padStartメソッドに渡された引数が、配列の長さよりも小さい場合、パディングは追加されません。


70. 何が出力されるでしょうか?
console.log("🥑" + "💻");
  • A: "🥑💻"
  • B: 257548
  • C: A string containing their code points
  • D: Error
答え

答え: A

+演算子を使うと、文字列を連結することができます。この場合、文字列"🥑"を文字列"💻"と連結して、結果として"🥑💻"となります。


71. console.logステートメントの後にコメントアウトされている値を、ログ出力する方法を教えてください。
function* startGame() {
  const answer = yield "Do you love JavaScript?";
  if (answer !== "Yes") {
    return "Oh wow... Guess we're gone here";
  }
  return "JavaScript loves you back ❤️";
}

const game = startGame();
console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️
  • A: game.next("Yes").value and game.next().value
  • B: game.next.value("Yes") and game.next.value()
  • C: game.next().value and game.next("Yes").value
  • D: game.next.value() and game.next.value("Yes")
答え

答え: C

ジェネレータ関数は、yieldキーワードを見るとその実行を「一時停止」します。まず、関数に文字列 "Do you love JavaScript?" を返させる必要があります。これは game.next().valueを呼び出すことによって行うことができます。

最初のyieldキーワードが見つかるまで、すべての行が実行されます。関数内の最初の行にyieldキーワードがあります: 実行は最初のyieldで停止します! これは変数 answerがまだ定義されていないことを意味します!

game.next("Yes").valueを呼び出すと、前のyieldnext()関数に渡されたパラメータの値、この場合は"Yes"に置き換えられます。変数answerの値は現在"Yes"となります。

if-statemnetの条件はfalseを返し、JavaScript loves you back ❤️が、出力されます。


72. 何が出力されるでしょうか?
console.log(String.raw`Hello\nworld`);
  • A: Hello world!
  • B: Hello
         world
  • C: Hello\nworld
  • D: Hello\n
         world
答え

答え: C

String.rawはエスケープ(\n, \v, \t など)を無視した文字列を返します。バックスラッシュは問題になる可能性があります:

const path = `C:\Documents\Projects\table.html`

これは次のようになります:

"C:DocumentsProjects able.html"

String.rawは、単にエスケープを無視して出力するだけです:

C:\Documents\Projects\table.html

上記の場合、文字列はHello\nworldと出力されます。


73. 何が出力されるでしょうか?
async function getData() {
  return await Promise.resolve("I made it!");
}

const data = getData();
console.log(data);
  • A: "I made it!"
  • B: Promise {<resolved>: "I made it!"}
  • C: Promise {<pending>}
  • D: undefined
答え

答え: C

非同期関数は常に、promiseを返します。awaitはpromiseが解決されるのを待たなければなりません: getData()を呼び出すと、dataは保留中のpromiseが返されます。

解決した値"I made it"にアクセスしたい場合は、dataに対して.then()メソッドを使用することができます:

data.then(res => console.log(res))

これは"I made it!"と出力するでしょう。


74. 何が出力されるでしょうか?
function addToList(item, list) {
  return list.push(item);
}

const result = addToList("apple", ["banana"]);
console.log(result);
  • A: ['apple', 'banana']
  • B: 2
  • C: true
  • D: undefined
答え

答え: B

.push()メソッドは新しい配列の長さを返します。以前は、配列は1つの要素(文字列 " banana ")を含み、長さは 1でした。文字列 " apple "を配列に追加した後、配列は2つの要素を含み、長さは 2になります。これは addToList関数から返されます。 The .push() method returns the length of the new array! Previously, the array contained one element (the string "banana") and had a length of 1. After adding the string "apple" to the array, the array contains two elements, and has a length of 2. This gets returned from the addToList function.

pushメソッドは元の配列を修正します。配列の長さではなく関数から配列を返したい場合は、itemをプッシュした後にlistを返すべきです。 The push method modifies the original array. If you wanted to return the array from the function rather than the length of the array, you should have returned list after pushing item to it.


75. 何が出力されるでしょうか?
const box = { x: 10, y: 20 };

Object.freeze(box);

const shape = box;
shape.x = 100;

console.log(shape);
  • A: { x: 100, y: 20 }
  • B: { x: 10, y: 20 }
  • C: { x: 100 }
  • D: ReferenceError
答え

答え: B

Object.freezeは、オブジェクトのプロパティを追加、削除、変更することを不可能にします(プロパティの値が他のオブジェクトのものでない限り)。

変数shapeを作成し、フリーズしたオブジェクトboxに代入すると、shapeはフリーズしたオブジェクトとなります。オブジェクトがフリーズしているかどうかは Object.isFrozenを使って確認できます。

この場合、変数shapeはフリーズしたオブジェクトへの参照を持っているので、Object.isFrozen(shape)はtrueを返します。

shapeはフリーズされており、xの値はオブジェクトではないので、プロパティxを変更することはできません。

x10のままとなり、{ x: 10, y: 20 }と出力されます。


76. 何が出力されるでしょうか?
const { name: myName } = { name: "Lydia" };

console.log(name);
  • A: "Lydia"
  • B: "myName"
  • C: undefined
  • D: ReferenceError
答え

答え: D

右側のオブジェクトからプロパティnameをアンパックするとき、その値"Lydia"myNameという名前の変数に代入します。

{name:myName}を使って、右側の nameプロパティの値でmyNameという新しい変数を作りたいことをJavaScriptに伝えます。

定義されていない変数nameを出力しようとしているので、ReferenceErrorが投げられます。


77. これは純粋関数でしょうか?
function sum(a, b) {
  return a + b;
}
  • A: Yes
  • B: No
答え

答え: A

純粋な関数は、同じ引数が渡された場合、常に 同じ結果を返す関数です。

sum関数は常に同じ結果を返します。12を渡すと、副作用なしに 常に 3 を返します。510を渡すと、常に 15が返され、以下同様に続きます。これが純粋関数の定義です。


78. 何が出力されるでしょうか?
const add = () => {
  const cache = {};
  return num => {
    if (num in cache) {
      return `From cache! ${cache[num]}`;
    } else {
      const result = num + 10;
      cache[num] = result;
      return `Calculated! ${result}`;
    }
  };
};

const addFunction = add();
console.log(addFunction(10));
console.log(addFunction(10));
console.log(addFunction(5 * 2));
  • A: Calculated! 20 Calculated! 20 Calculated! 20
  • B: Calculated! 20 From cache! 20 Calculated! 20
  • C: Calculated! 20 From cache! 20 From cache! 20
  • D: Calculated! 20 From cache! 20 Error
答え

答え: C

add関数は memoized 関数です。メモ化により、実行速度を上げるために関数の結果をキャッシュすることができます。上記の場合、以前に返された値を格納するcacheオブジェクトを作成します。

同じ引数を指定してもう一度addFunction関数を呼び出すと、最初にキャッシュ内でその値がすでに取得されているかどうかを調べます。

この場合、cachesの値が返され、実行時間が短縮されます。そうでなくキャッシュされていなければ、値を計算した後にそれを格納します。

同じ値で3回addFunction関数を呼び出します: 最初の呼び出しでは、num10を代入した時、関数の値はまだキャッシュされていません。

ifステートメントのnum in cacheの条件はfalseを返し、elseブロックが実行されます: Calculated! 20が出力され、結果の値がキャッシュオブジェクトに追加されます。 cacheは現在 { 10: 20 }となります。

2回目は、cacheオブジェクトは10に対して返される値を含みます。 ifステートメントのnum in cacheの条件はtrueとなり、'From cache! 20'を返します。 よって'From cache! 20'が出力されます。

3回目は、10に評価される関数に5 * 2を渡します。cacheオブジェクトは10に対して返される値を含みます。ifステートメントのnum in cacheの条件はtrueとなり、'From cache! 20'を返します。 よって'From cache! 20'が出力されます。


79. 何が出力されるでしょうか?
const myLifeSummedUp = ["☕", "💻", "🍷", "🍫"]

for (let item in myLifeSummedUp) {
  console.log(item)
}

for (let item of myLifeSummedUp) {
  console.log(item)
}
  • A: 0 1 2 3 and "☕" "💻" "🍷" "🍫"
  • B: "☕" "💻" "🍷" "🍫" and "☕" "💻" "🍷" "🍫"
  • C: "☕" "💻" "🍷" "🍫" and 0 1 2 3
  • D: 0 1 2 3 and {0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}
答え

答え: A

for-in ループを使うと、列挙可能なプロパティを繰り返し処理できます。配列では、列挙可能なプロパティは配列要素の「キー」です。これはそれらのインデックスとなり、配列は次のようになります:

{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}

キーが列挙可能なプロパティであるので、0 1 2 3が出力されます。

for-of ループを使うと、反復可能オブジェクトを繰り返し処理できます。

配列はイテラブルです。配列を反復処理するとき、変数 "item"は、現在反復処理している要素となるので、"☕" "💻" "🍷" "🍫"が出力されます。


80. 何が出力されるでしょうか?
const list = [1 + 2, 1 * 2, 1 / 2]
console.log(list)
  • A: ["1 + 2", "1 * 2", "1 / 2"]
  • B: ["12", 2, 0.5]
  • C: [3, 2, 0.5]
  • D: [1, 1, 1]
答え

答え: C

配列要素は任意の値を保持できます。数値、文字列、オブジェクト、その他の配列、null、ブール値、undefined、および日付、関数、計算などのその他の式。

要素は戻り値と等しくなります。1 + 23を返し、1 * 22を返し、1 / 20.5を返します。


81. 何が出力されるでしょうか?
function sayHi(name) {
  return `Hi there, ${name}`
}

console.log(sayHi())
  • A: Hi there,
  • B: Hi there, undefined
  • C: Hi there, null
  • D: ReferenceError
答え

答え: B

関数に値が渡されていない限り、引数はデフォルトでundefinedの値を持ちます。上記の場合、name引数に値を渡さなかったので、nameundefinedとなり出力されます。

ES6では、このデフォルトのundefined値を、デフォルトパラメータで上書きすることができます。例:

function sayHi(name = "Lydia") { ... }

上記の場合、値を渡さなかった場合や、undefinedを渡した場合は、nameは常に文字列Lydiaとなります。


82. 何が出力されるでしょうか?
var status = "😎"

setTimeout(() => {
  const status = "😍"

  const data = {
    status: "🥑",
    getStatus() {
      return this.status
    }
  }

  console.log(data.getStatus())
  console.log(data.getStatus.call(this))
}, 0)
  • A: "🥑" and "😍"
  • B: "🥑" and "😎"
  • C: "😍" and "😎"
  • D: "😎" and "😎"
答え

答え: B

thisキーワードの値は使う場所に依存します。 メソッドの中では、getStatusメソッドのように、thisキーワードは メソッドが属するオブジェクトを参照します

メソッドはdataオブジェクトに属しているので、thisdataオブジェクトを参照します。 this.statusをログ出力すると、dataオブジェクトのstatusプロパティの"🥑"がログ出力されます。

callメソッドを使うと、thisキーワードが参照するオブジェクトを変更することができます。 関数では、thisキーワードは その関数が属するオブジェクトを参照します

グローバルオブジェクトで setTimeout関数を宣言したので、setTimeout関数内では、 thisキーワードは グローバルオブジェクト を参照します。

グローバルオブジェクト上には、値"😎"を持つ status という変数があります。this.statusを出力すると、"😎"が出力されます。


83. 何が出力されるでしょうか?
const person = {
  name: "Lydia",
  age: 21
}

let city = person.city
city = "Amsterdam"

console.log(person)
  • A: { name: "Lydia", age: 21 }
  • B: { name: "Lydia", age: 21, city: "Amsterdam" }
  • C: { name: "Lydia", age: 21, city: undefined }
  • D: "Amsterdam"
答え

答え: A

変数cityに、personオブジェクトのcityという名前のプロパティの値を代入します。このオブジェクトにはcityという名前のプロパティはないので、変数cityundefinedの値を持ちます。

我々はpersonオブジェクト自身を参照して いない ことに注意してください。personオブジェクトのcityプロパティを、変数cityに代入するだけです。

それから、cityに、文字列"Amsterdam"を代入しますこれは personオブジェクトを変更しません: そのオブジェクトへの参照はありません。

personオブジェクトをログ出力するとき、未修正のオブジェクトが返されます。


84. 何が出力されるでしょうか?
function checkAge(age) {
  if (age < 18) {
    const message = "Sorry, you're too young."
  } else {
    const message = "Yay! You're old enough!"
  }

  return message
}

console.log(checkAge(21))
  • A: "Sorry, you're too young."
  • B: "Yay! You're old enough!"
  • C: ReferenceError
  • D: undefined
答え

答え: C

constletキーワードを持つ変数は ブロックスコープ です。ブロックは中括弧({ })で囲まれたものです。上記の場合、if/elseステートメントが中括弧となります。宣言されたブロックの外側で変数を参照することはできません。ReferenceError がスローされます。


85. どのような情報が出力されますか?
fetch('https://www.website.com/api/user/1')
  .then(res => res.json())
  .then(res => console.log(res))
  • A: fetchメソッドの結果
  • B: 2回目の fetchメソッド呼び出しの結果
  • C: 前の.then()でのコールバックの結果
  • D: 常に undefined.
答え

答え: C

2番目の.thenresの値は、前の.thenの戻り値と同じとなります。値が次のハンドラに渡されるように、.thenを連鎖させることができます。


86. 引数としてtrueを渡すことができない場合、どのオプションがhasNametrueに設定するための方法ですか?
function getName(name) {
  const hasName = //
}
  • A: !!name
  • B: name
  • C: new Boolean(name)
  • D: name.length
答え

答え: A

!!nameを使って、nameの値が、truthyか falseyかを判断します。nameがtruthyであり、これをテストしたい場合、!namefalseを返します。!false(これは実際には!!nameです)はtrueを返します。

hasNamenameを代入することで、getName関数に渡されたどんな値もhasNameに代入されます。ブール値trueは設定できません。

new Boolean(true)は、ブール値そのものではなく、オブジェクトラッパーを返します。

name.lengthは渡された引数の長さを返します。それがtrueであるかどうかではありません。