Salesforce 認定 JavaScript デベロッパー の勉強メモ
Winter '21 の時に書いたメモです
2020 年 11 月に日本語版が出たばかりの資格です。
JavaScript はいままでなんとなく触ってきた感じだったので、体系だって勉強し直してみるのも良いかなぁ、くらいのモチベーションで受けました。勉強メモは備忘録、およびリンク集として残しています。
なお、資格名に Salesforce の文字は入ってますが、Salesforce に関する知識は不要で、純粋に JavaScript に関する問題が出題されるとのことです。
https://gyazo.com/68e39e63708da408921b51586e69efaf
リンク集
Trailhead (Trailmix)
この (↑) Trailmix がドンピシャなモジュールを集めたやつっぽいです
簡単にクリアできますが概要を掴むのに良いかと思います
JavaScript の有名な問題集 on Github
気になる
↑ とてもわかりやすいです。ただし分量が多い。。
MDN 公式
JavaScript の Playground
* JavaScript は、F12 をクリックしてブラウザの開発者モードの Console タブでも気軽に実行できます
勉強中はこっちで検証することが多かったかも
ForcusOnForce (お金に余裕があれば)
受験記
海外ブログ
勉強方法
1. 受験ガイドをみる
2. 公式 Trailmix をやってみる
3. ブログ記事や受験記をみて傾向を掴む
5. JavaScript の有名な問題集 on Github を全部やってみる
個人的におすすめな書籍
言語仕様に関する書籍なので、本試験の対策としてはかなり有用だと思いました
まったくの初歩から書かれているわけではないので、私のように今まで雰囲気で JavaScript を書いていたよ、みたいな方におすすめしたいです
本試験の 変数、データ型、コレクション, オブジェクト、関数、クラス の章はこの本を読めばかなり対策ができます
逆に言うと、非同期とか node.js とかのトピックはまったくでてきません
O'REILLY 本ですが、170 ページ程度ですので、サクっと読めます
受験ガイドからの引用
受験ガイドでは出題範囲が載っているので、以下に受験ガイドから出題範囲を引用して、参考になりそうなドキュメントのリンクを紐づけていきます。(復習のためです)
変数、データ型、コレクション: 23%
シナリオに基づき、変数を作成して正しく初期化するコードを記述する。
たぶん var, let, const とかの変数宣言のスコープのことだと思う
変数宣言
初期化
変数宣言だけして代入しなかったら undefined になる
巻き上げ (ホイスティング) も JavaScript の特徴なので出題されそう
関数定義や、モジュール読み込み (import)、変数定義が巻き上げられる
var と let は巻き上げられ方が異なるので注意
code:JavaScript
'use strict';
// 書き換え不可能なグローバルへの代入
var undefined = 5; // TypeError を投げます
var Infinity = 5; // TypeError を投げます
// 書き換え不可能なプロパティへの代入
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // TypeError を投げます
// ゲッター専用プロパティへの代入
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError を投げます
// 拡張不可能なオブジェクトの新しいプロパティへの代入
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // TypeError を投げます
var とか let がない変数宣言もエラーになる
ビジネス要件に基づき、文字列、数値、日付を効果的に利用する。
プリミティブ型の持っているメソッドは一通りみていきます。(知らないの結構ある。。。)
code: JavaScript
let count = 10;
console.log(count.toString()); // displays '10'
console.log(x.toString(2)); // displays '1010'
let numObj = 12345.6789
numObj.toFixed() // Returns '12346': note rounding, no fractional part
numObj.toFixed(1) // Returns '12345.7': note rounding
getMonth() メソッドは、地方時に基づき、指定された日付の「月」を表す 0 を基点とした値 (すなわち 0 が年の最初の月を示す) を返します。
↑わかりずらいな・・・
code: JavaScript
const moonLanding = new Date('July 20, 69 00:20:18');
console.log(moonLanding.getMonth());
// July は 7 月だけど、実際は 6 を返す
数値型 + 文字列の足し算 -> 文字列の足し算になる
日付型 + 数値型の足し算も同様 -> 文字列の足し算になる
console.log(true + 1); // 2 になる
console.log(null + 1); // 1 になる
console.log('abc' + null); // abcnull になる
シナリオまたは例に基づき、型強制とその影響を認識していることを示す。
JavaScript は暗黙的な型変換が発生しやすいですね。。。
JavaScript は弱い型付けあるいは動的型付けの言語です。
関数にプリミティブ型が渡された場合は値渡し、オブジェクトが渡された場合は参照渡し (重要)
code: JavaScript
const value1 = '5';
const value2 = 9;
let sum = value1 + value2;
console.log(sum); // displays '59', not 14
特定のシナリオに基づき、truthy または falsey な評価を区別する。
falsey...? 受験ガイドが typo してますね。falsy です。何を true とするか、false とするか、言語系によって違います。
code: JavaScript
if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
※ {} とか [] とか "0" は個人的には falsy っぽいけど truthy になるやつなので要チェック
new Number(0) や new Boolean(false) も試して見たら true となった。オブジェクトは truthy らしい。
code: JavaScript
if (false)
if (null)
if (undefined)
if (0)
if (-0)
if (0n)
if (NaN)
if ("")
※空文字 "" は falsy (空配列は truthy なのにね。紛らわしいなぁ)
データのリストに基づき、配列を使用したデータ操作を示す。
配列を使用したデータ操作... Array のインスタンスメソッド (多すぎて覚えられない...)。
よく使いそう&自分の記憶があいまいだったのだけ抜き出します。(あとで全部見直す)
配列から特定要素を条件に基づいてフィルタリングした配列を返却
code: JavaScript
const result = words.filter(word => word.length > 6);
console.log(result);
配列に対して繰り返し処理をして、新しい配列を返却
code: JavaScript
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
配列をぐるぐる
code:JavaScript
array1.forEach(element => console.log(element));
// expected output: "a"
// expected output: "b"
// expected output: "c"
ソート関数を指定する方法もある
code: JavaScript
console.log(array1.sort());
// 文字列順番でソートされてしまう
console.log(array1.sort((a, b) => a - b));
// 引数の比較関数の返値に基づきソートされる
配列から単一の値を出力する
code: JavaScript
const reducer = (accumulator, currentValue) => accumulator.concat(currentValue);
console.log(array1.reduce(reducer, 'd'));
// expected output: dabc
// 個人的には直感的じゃないなぁ、output は abcd になって欲しかった...
配列を展開する時に使う (らしい)
code: JavaScript
console.log(arr);
JSON 応答に基づき、JSON オブジェクトの操作方法を示す。
JSON.parse() は単一引用符を許容しない
code: JavaScript
JSON.parse("{'foo': 1}"); // NG: SyntaxError が発生
JSON.parse('{"foo": 1}'); // OK: {foo: 1}
オブジェクト、関数、クラス: 25%:
ビジネス要件に基づき、最良の関数実装を見つける。
関数に渡す引数が複数になる場合に利用できる
code: JavaScript
function myConcat(separator) {
let args = Array.prototype.slice.call(arguments, 1);
return args.join(separator);
}
// "red, orange, blue" を返します
myConcat(', ', 'red', 'orange', 'blue');
// "elephant; giraffe; lion; cheetah" を返します
myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
// "sage. basil. oregano. pepper. parsley" を返します
myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
アロー関数を覚えるのは慣れしかないのか・・・
あるオブジェクトに所属する関数やメソッドを、別なオブジェクトに割り当てて呼び出す
引数の渡し方が異なる
ビジネス要件に基づき、オブジェクト実装の基本を適用し、ビジネス要件を解決する。
↑とても重要です。 謎だった MDN の読み方への理解が深まりました
new の仲間
コピーを行う。変数名が同じだった場合には source で上書きされる。
code: JavaScript
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
オブジェクトが持つプロパティの組みを配列として出力する。for...in の構文中とかで使われる
変更できなくする。オブジェクトの const 的な感じかなぁ。
ビジネス要件に基づき、クラス実装の基本を適用し、ビジネス要件を解決する。
ref: "constructor" という名前の特別なメソッドは、クラスに 1 つしか定義できません。
Apex だと複数定義できるのに、JavaScript だとできない。SyntaxError になる。
オーバーロードはできないのかな。
与えられた JavaScript モジュールで、モジュールの使用方法の例を示す。
ref: インポートされた機能はファイル内で利用できますが、エクスポートされた機能の読み取り専用ビューです。
ref: インポートされた変数を変更することはできませんが、const と同様にプロパティを変更することはできます。
code: JavaScript
import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , ... } from "module-name"; import defaultExport, { export1 [ , ... ] } from "module-name"; import defaultExport, * as name from "module-name";
import "module-name";
var promise = import("module-name");
function 名を指定する。* でメソッドを全部インポート
動的インポート (評価時にインポートされる)
code:JavaScript
import('/modules/my-module.js')
.then((module) => {
// Do something with the module.
});
code:JavaScript
// 名前付きエクスポート
// 事前に宣言された機能のエクスポート
export { myFunction, myVariable };
// 個別の機能のエクスポート
// (var, let, const, function, class がエクスポート可能)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };
// デフォルトエクスポート
// デフォルトとして事前に定義された機能のエクスポート
export { myFunction as default };
// 個別の機能をデフォルトとしてエクスポート
export default function () { ... }
export default class { .. }
// 各エクスポートは前のエクスポートを上書きします
与えられた JavaScript デコレータで、デコレータの使用方法の例を示す。
ref: デコレーターを使う理由は、ラッパーを簡素なコードで書けるため、コードの意図が読み取りやすくなることです。
与えられたコードブロックで、変数のスコープと実行フローを分析する。
変数のスコープ
this は奥が深いです
実行フロー
ブラウザとイベント: 17%
ビジネス要件に基づき、イベント、イベントハンドラー、イベント伝達を利用する。
特定の DOM 要素に対してイベントリスナを登録する
文法に注意:on のプリフィックスは不要
キャプチャリングとバブリング
キャプチャリング -> ターゲット -> バブリング の順番
伝搬を止める
例えば、余計な上位オブジェクトのイベントリスナを起動させずに特定のオブジェクトのイベントのみを起動させるばい等がユースケース
既定の動作を止める場合に利用
例えば、エラーハンドリングでエラーになる場合は form を submit しないようにする、等のユースケース
クライアントサイドの Validation を実装したときに使ったことがあったなぁ
文法に注意:on のプリフィックスが必要
カスタムイベントを作って、dispatchEvent で発火させる
code: JavaScript
// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) });
// create and dispatch the event
var event = new CustomEvent("cat", {
detail: {
hazcheeseburger: true
}
});
obj.dispatchEvent(event);
ビジネス要件に基づき、DOM を評価および操作する。
JavaScript のセレクタ
getElementsByClassName() とかもあるけどあまり使われてるのを見たことがない
getElements と複数形になっていることがポイント。SelectAll もそうだけど、複数要素が返ってくる
シナリオに基づき、ブラウザ開発ツールを利用してコードの動作を調査する。
Slow 3G mode
F12 キーを押して開発者モードにした後にブラウザの更新ボタンを長押し(この方法は知りませんでした・・・!!)
minified された JavaScript を読みやすく変換する
知らない機能がたくさん、、色々できるんですね・・・!!
シナリオと要件に基づき、ブラウザ固有の API を利用する。
new URL("https://developer.mozilla.org/en-US/docs/Web/API/URL_API"); みたいな使い方
いろんなプロパティを持ってるみたい
JavaScript でブラウザ上でお絵かきする時に使う
pushState() でブラウザの履歴を JavaScript で追加できる
popstate は戻るボタンをクリック (history.back()) した時を onpopstate でハンドリングできる
1 つ戻る:history.go(-1)
1 つ進む:history.go(1)
リロード:history.go(); or history.go(0);
sessionStorage
ページセッションの間 (ブラウザーを開いている間、ページの再読み込みや復元を含む) に使用可能
localStorage
ブラウザーを閉じたり再び開いたりしても持続する
Safari はプライベートブラウジングモードで localStorage が使えないなど、固有の要件がある
デバッグとエラーハンドリング: 7%
シナリオに基づき、エラーを適切に処理する。
基本中の基本ですね
finally も使えます
code: JavaScript
try {
nonExistentFunction();
} catch (error) {
console.error(error);
} finally {
// finally_statements here.
}
オブジェクト定義。どんな型、プロパティ、メソッドを持っているかを覚えておく
こんな感じ throw 'Parameter is not a number!'; (JavaScript では Exception を new しなくても投げられる)
たぶん一番よく使うやつ。これくらいしか使ってませんでしたが、他にも色々あるんですね・・・!!
赤いメッセージ (ブラウザ依存) でログを出せる。console.warn() で黄色い (ブラウザ依存) ログも出せる。
console.time(label); でタイマー開始、console.timeEnd(label) で経過時間表示
配列やオブジェクトを渡すことによって Console に表形式のデータを表示させることができる
非標準とのこと
Google Chrome 公式ドキュメント
デバッグするために与えられたコードで、コンソールとブレークポイントを使用する。
Google Chrome 公式ドキュメント
コード行のブレイクポイントだけでなく、DOM 変更のタイミングとか、XHR リクエストのタイミングとか、イベントリスナー、例外、関数、でも一時停止できることが説明されてる (使ったことなかったなぁ)
ブラウザ機能のブレイクポイントではなく、明示的に JavaScript ソースに記述するときは、debugger; を呼び出す
非同期プログラミング: 13%
シナリオに基づき、非同期プログラミングの概念を適用する。
Promise とかですよね、めっちゃ苦手です...
非同期とは?から書いてあるのでわかりやすいです
JavaScript はシングルスレッドです
async で非同期関数を定義する。結果として Promise が返ってくる
非同期関数の中では await が使える。await では非同期関数の実行を待つことができる
以下の違いを明確にしておく
then メソッドを使うプロミスチェーンも覚えておく
then の実行順に注意 (リファレンスのサンプルコード参照)
then は async await で代替することも可能。代替の書き方に関するサンプル問題が Trailhead にあった
async function の中で、await が利用可能
code: 引用
Promise の状態は以下のいずれかとなります。
待機 pending: 初期状態。成功も失敗もしていません。
満足 fulfilled: 処理が成功して完了したことを意味します。
拒絶 rejected: 処理が失敗したことを意味します。
待機、満足、拒絶の 3 つの状態がある。 日本語訳あってるのか・・・?
どうでもいい話ですが、"コールバック地獄" ってよく聞きますが、英語でも callback hell っていうんですね。
シナリオに基づき、イベントループとイベント監視を使用する、またはループの結果を判断する。
ここの図がわかりやすい
再帰関数はスタックに格納されるし、後述の setInterval 等はメッセージキューに格納される
スタックが空になってからキューが FIFO で実行される (実行順に注意)
非同期的に処理される
setInterval の第二引数の秒数ごとに第一引数の関数を実行、clearInterval で解除
非同期的に処理される
setTimeout の第二引数の秒数後に第一引数の関数を実行
JavaScript で監視できるイベントの一覧。対応するイベントリスナーや monitorEvents に追加することで監視が可能
サーバーサイド JAVASCRIPT: 8%
シナリオと要件に基づき、Node.js のどの実装が適切なソリューションであるかを推測する。
code: JavaScript
const https = require('https');
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
}).on('error', (e) => {
console.error(e);
});
シナリオと要件に基づき、Node.js のどの CLI コマンドが適切なソリューションであるかを推測する。
debug: node --inspection index.js
node -c: syntax check without code execution.
node -e: evaluate execution.
npm i <package 名>: install package.
npm up <package 名>: update package.
Node.js のコアモジュールと特定のシナリオに基づき、Node.js のどの library/framework が適切なソリューションであるかを推測する。
公式サイトではありませんが、コアモジュールが一覧で載ってます
^:同じメジャーバージョンの範囲内で、指定したマイナーバージョン、パッチバーション以上
~:同じメジャーバージョン、マイナーバージョンの範囲内で、指定したパッチバージョン以上
シナリオと要件に基づき、どの Node.js パッケージ管理ソリューションが最適であるかを区別する。
Lodash, Axios, Express, React ぐらいの概要、簡単な使い方を覚える
Lodash: 便利な関数をまとめて提供しているライブラリ
Axios: Promise ベースの HTTP クライアント
Express: Web アプリケーションフレームワーク
React: UI を作ることに特化したライブラリ
Chalk: ターミナル文字列のスタイリングをしてくれるパッケージ
テスト: 7%
コードブロックと関連する単体テストを使用して、テストが効果的ではない部分を判断し、より効果的になるように変更する。
Jest とかもでるのかな・・・?(Trailhead くらいでしかやったことがない...)
この単元は 7% しかでないので捨てます。笑
受験後の感想
上でまとめたように自分では結構勉強したつもりでしたが、受験中はまったく手応えを感じませんでした。。。試験の提出ボタンを押す時はかなり緊張しましたが、無事に合格でした!
Server Side JavaScript(サーバーサイドJavaScript) の単元は 20% しかとれませんでした・・・まとめ中も思いましたが、これどうやって勉強したら良いかわからないですね。