Salesforce 認定 JavaScript デベロッパー の勉強メモ
Winter '21 の時に書いたメモです
2020 年 11 月に日本語版が出たばかりの資格です。
JavaScript はいままでなんとなく触ってきた感じだったので、体系だって勉強し直してみるのも良いかなぁ、くらいのモチベーションで受けました。勉強メモは備忘録、およびリンク集として残しています。
なお、資格名に Salesforce の文字は入ってますが、Salesforce に関する知識は不要で、純粋に JavaScript に関する問題が出題されるとのことです。
https://gyazo.com/68e39e63708da408921b51586e69efaf
リンク集
受験ガイド
Trailhead (Trailmix)
Study for the Salesforce JavaScript Developer I Exam
この (↑) Trailmix がドンピシャなモジュールを集めたやつっぽいです
簡単にクリアできますが概要を掴むのに良いかと思います
Prepare for your Salesforce JavaScript Developer I Credential
JavaScript の有名な問題集 on Github
https://github.com/lydiahallie/javascript-questions
気になる
Everything you need to know from ES2016 to ES2019
日本語訳
The Modern JavaScript Tutorial
↑ とてもわかりやすいです。ただし分量が多い。。
MDN 公式
JavaScript ガイド
JavaScript リファレンス
JavaScript の Playground
https://jsfiddle.net/
* JavaScript は、F12 をクリックしてブラウザの開発者モードの Console タブでも気軽に実行できます
勉強中はこっちで検証することが多かったかも
ForcusOnForce (お金に余裕があれば)
参考書
問題集
受験記
@takahito0508 -san https://qiita.com/takahito0508/items/6c6b50cd3c546ea44272
@arufian -san https://qiita.com/arufian/items/5b3e1f20c73bf71cd8e3
海外ブログ
Passing the Salesforce JavaScript Developer 1 Certification
Tips for passing Salesforce certified JavaScript Developer I Certification
Tips for passing Salesforce JavaScript Developer Certification
勉強方法
1. 受験ガイドをみる
2. 公式 Trailmix をやってみる
3. ブログ記事や受験記をみて傾向を掴む
4. MDN 公式のガイド、リファレンス or The Modern JavaScript Tutorial を上から全部読んでいく
5. JavaScript の有名な問題集 on Github を全部やってみる
個人的におすすめな書籍
開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質
言語仕様に関する書籍なので、本試験の対策としてはかなり有用だと思いました
まったくの初歩から書かれているわけではないので、私のように今まで雰囲気で JavaScript を書いていたよ、みたいな方におすすめしたいです
本試験の 変数、データ型、コレクション, オブジェクト、関数、クラス の章はこの本を読めばかなり対策ができます
逆に言うと、非同期とか node.js とかのトピックはまったくでてきません
O'REILLY 本ですが、170 ページ程度ですので、サクっと読めます
受験ガイドからの引用
受験ガイドでは出題範囲が載っているので、以下に受験ガイドから出題範囲を引用して、参考になりそうなドキュメントのリンクを紐づけていきます。(復習のためです)
変数、データ型、コレクション: 23%
シナリオに基づき、変数を作成して正しく初期化するコードを記述する。
たぶん var, let, const とかの変数宣言のスコープのことだと思う
変数宣言
var
let
const
初期化
変数宣言だけして代入しなかったら undefined になる
undefined
巻き上げ (ホイスティング) も JavaScript の特徴なので出題されそう
関数定義や、モジュール読み込み (import)、変数定義が巻き上げられる
var と let は巻き上げられ方が異なるので注意
teratail: letとconstの巻き上げは起こりますか?
Strict モード
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
日付
Date.prototype.getMonth()
getMonth() メソッドは、地方時に基づき、指定された日付の「月」を表す 0 を基点とした値 (すなわち 0 が年の最初の月を示す) を返します。
↑わかりずらいな・・・
code: JavaScript
const moonLanding = new Date('July 20, 69 00:20:18');
console.log(moonLanding.getMonth());
// July は 7 月だけど、実際は 6 を返す
BigInt
teratail: javascriptで文字列結合と数値の足し算がうまくいきません!
数値型 + 文字列の足し算 -> 文字列の足し算になる
日付型 + 数値型の足し算も同様 -> 文字列の足し算になる
console.log(true + 1); // 2 になる
console.log(null + 1); // 1 になる
console.log('abc' + null); // abcnull になる
シナリオまたは例に基づき、型強制とその影響を認識していることを示す。
JavaScript は暗黙的な型変換が発生しやすいですね。。。
JavaScript のデータ型とデータ構造
JavaScript は弱い型付けあるいは動的型付けの言語です。
関数にプリミティブ型が渡された場合は値渡し、オブジェクトが渡された場合は参照渡し (重要)
型強制
code: JavaScript
const value1 = '5';
const value2 = 9;
let sum = value1 + value2;
console.log(sum); // displays '59', not 14
厳密等価
Qiita 記事: JavaScriptのプリミティブへの変換を完全に理解する
Qiita 記事: JavaScriptの等値比較を全部理解する
特定のシナリオに基づき、truthy または falsey な評価を区別する。
falsey...? 受験ガイドが typo してますね。falsy です。何を true とするか、false とするか、言語系によって違います。
truthy
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 らしい。
falsy
code: JavaScript
if (false)
if (null)
if (undefined)
if (0)
if (-0)
if (0n)
if (NaN)
if ("")
※空文字 "" は falsy (空配列は truthy なのにね。紛らわしいなぁ)
データのリストに基づき、配列を使用したデータ操作を示す。
配列を使用したデータ操作... Array のインスタンスメソッド (多すぎて覚えられない...)。
配列
よく使いそう&自分の記憶があいまいだったのだけ抜き出します。(あとで全部見直す)
filter
配列から特定要素を条件に基づいてフィルタリングした配列を返却
code: JavaScript
const words = 'spray', 'limit', 'elite', 'exuberant', 'destruction', 'present';
const result = words.filter(word => word.length > 6);
console.log(result);
// expected output: Array "exuberant", "destruction", "present"
map
配列に対して繰り返し処理をして、新しい配列を返却
code: JavaScript
const array1 = 1, 4, 9, 16;
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array 2, 8, 18, 32
forEach
配列をぐるぐる
code:JavaScript
const array1 = 'a', 'b', 'c';
array1.forEach(element => console.log(element));
// expected output: "a"
// expected output: "b"
// expected output: "c"
sort
ソート関数を指定する方法もある
code: JavaScript
const array1 = 7, 3, 400, 10;
console.log(array1.sort());
// expected output: 10, 3, 400, 7
// 文字列順番でソートされてしまう
console.log(array1.sort((a, b) => a - b));
// expected output: 3, 7, 10, 400
// 引数の比較関数の返値に基づきソートされる
reduce
配列から単一の値を出力する
code: JavaScript
const array1 = 'a', 'b', 'c';
const reducer = (accumulator, currentValue) => accumulator.concat(currentValue);
console.log(array1.reduce(reducer, 'd'));
// expected output: dabc
// 個人的には直感的じゃないなぁ、output は abcd になって欲しかった...
スプレッド構文
配列を展開する時に使う (らしい)
code: JavaScript
let arr1 = 0, 1, 2;
let arr2 = 3, 4, 5;
arr1 = ...arr2, ...arr1;
// arr1 is now 3, 4, 5, 0, 1, 2
let arr = ...'abcde';
console.log(arr);
// "a", "b", "c", "d", "e"
JSON 応答に基づき、JSON オブジェクトの操作方法を示す。
JSON
JSON.stringify()
JSON.parse()
JSON.parse() は単一引用符を許容しない
code: JavaScript
JSON.parse("{'foo': 1}"); // NG: SyntaxError が発生
JSON.parse('{"foo": 1}'); // OK: {foo: 1}
オブジェクト、関数、クラス: 25%:
ビジネス要件に基づき、最良の関数実装を見つける。
関数宣言
arguments
関数に渡す引数が複数になる場合に利用できる
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');
イテレーターとジェネレーター
Qiita 記事: JavaScript の イテレータ を極める!
Qiita 記事: JavaScript の ジェネレータ を極める!
アロー関数
Qiita 記事: JavaScript アロー関数を説明するよ
アロー関数を覚えるのは慣れしかないのか・・・
クロージャ
Function.prototype.call()
あるオブジェクトに所属する関数やメソッドを、別なオブジェクトに割り当てて呼び出す
Function.prototype.apply() の仲間
引数の渡し方が異なる
テンプレートリテラル
ビジネス要件に基づき、オブジェクト実装の基本を適用し、ビジネス要件を解決する。
JavaScript オブジェクトの基本
JavaScript での継承
https://jsfiddle.net/17ycvumf/#&togetherjs=yR5Qu0L7cm
Object のプロトタイプ
Qiita 記事: 図で理解するJavaScriptのプロトタイプチェーン
↑とても重要です。 謎だった MDN の読み方への理解が深まりました
オブジェクトでの作業
Object.create()
new の仲間
Object.assign()
コピーを行う。変数名が同じだった場合には 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 }
Object.entries()
オブジェクトが持つプロパティの組みを配列として出力する。for...in の構文中とかで使われる
Object.freeze()
変更できなくする。オブジェクトの const 的な感じかなぁ。
ビジネス要件に基づき、クラス実装の基本を適用し、ビジネス要件を解決する。
クラス
ref: "constructor" という名前の特別なメソッドは、クラスに 1 つしか定義できません。
Apex だと複数定義できるのに、JavaScript だとできない。SyntaxError になる。
オーバーロードはできないのかな。
与えられた JavaScript モジュールで、モジュールの使用方法の例を示す。
JavaScript モジュール
記事中でいくつかの サンプル が紹介されてます
ref: インポートされた機能はファイル内で利用できますが、エクスポートされた機能の読み取り専用ビューです。
ref: インポートされた変数を変更することはできませんが、const と同様にプロパティを変更することはできます。
import
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.
});
export
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 デコレータで、デコレータの使用方法の例を示す。
Qiita 記事:JavaScript の デコレータ の使い方
きれいで読みやすいJavaScriptを書く デコレーターの基本を先取り
ref: デコレーターを使う理由は、ラッパーを簡素なコードで書けるため、コードの意図が読み取りやすくなることです。
与えられたコードブロックで、変数のスコープと実行フローを分析する。
変数のスコープ
this
this は奥が深いです
実行フロー
並行モデルとイベントループ
Call stack (コールスタック)
ブラウザとイベント: 17%
ビジネス要件に基づき、イベント、イベントハンドラー、イベント伝達を利用する。
EventTarget.addEventListener()
特定の DOM 要素に対してイベントリスナを登録する
文法に注意:on のプリフィックスは不要
Event.target とEvent.currentTarget の違いを明確にしておく
EventTarget.removeEventListener()
キャプチャリングとバブリング
ちゃんと知ってる?JavaScriptのイベントバブリングを学ぼう
キャプチャリング -> ターゲット -> バブリング の順番
Event.stopPropagation()
伝搬を止める
例えば、余計な上位オブジェクトのイベントリスナを起動させずに特定のオブジェクトのイベントのみを起動させるばい等がユースケース
Event.preventDefault()
既定の動作を止める場合に利用
例えば、エラーハンドリングでエラーになる場合は form を submit しないようにする、等のユースケース
クライアントサイドの Validation を実装したときに使ったことがあったなぁ
DOM onevent ハンドラー
文法に注意:on のプリフィックスが必要
CustomEvent()
カスタムイベントを作って、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 のセレクタ
Document.getElementById()
Document.querySelector()
Document.querySelectorAll()
getElementsByClassName() とかもあるけどあまり使われてるのを見たことがない
getElements と複数形になっていることがポイント。SelectAll もそうだけど、複数要素が返ってくる
シナリオに基づき、ブラウザ開発ツールを利用してコードの動作を調査する。
回線が遅い場合のテスト
Slow 3G mode
スーパーリロード
F12 キーを押して開発者モードにした後にブラウザの更新ボタンを長押し(この方法は知りませんでした・・・!!)
読みやすい形式への JavaScript の変換
minified された JavaScript を読みやすく変換する
Network Analysis Reference
知らない機能がたくさん、、色々できるんですね・・・!!
シナリオと要件に基づき、ブラウザ固有の API を利用する。
URL API
new URL("https://developer.mozilla.org/en-US/docs/Web/API/URL_API"); みたいな使い方
いろんなプロパティを持ってるみたい
Canvas API
JavaScript でブラウザ上でお絵かきする時に使う
History API
History API を取り扱う
pushState() でブラウザの履歴を JavaScript で追加できる
popstate は戻るボタンをクリック (history.back()) した時を onpopstate でハンドリングできる
History.go() で履歴の移動を行う
1 つ戻る:history.go(-1)
1 つ進む:history.go(1)
リロード:history.go(); or history.go(0);
Web Storage API
Web Storage API の使用
sessionStorage
ページセッションの間 (ブラウザーを開いている間、ページの再読み込みや復元を含む) に使用可能
localStorage
ブラウザーを閉じたり再び開いたりしても持続する
Safari はプライベートブラウジングモードで localStorage が使えないなど、固有の要件がある
デバッグとエラーハンドリング: 7%
シナリオに基づき、エラーを適切に処理する。
try...catch
基本中の基本ですね
finally も使えます
code: JavaScript
try {
nonExistentFunction();
} catch (error) {
console.error(error);
} finally {
// finally_statements here.
}
Error
オブジェクト定義。どんな型、プロパティ、メソッドを持っているかを覚えておく
throw
こんな感じ throw 'Parameter is not a number!'; (JavaScript では Exception を new しなくても投げられる)
console
console.log()
たぶん一番よく使うやつ。これくらいしか使ってませんでしたが、他にも色々あるんですね・・・!!
console.error()
赤いメッセージ (ブラウザ依存) でログを出せる。console.warn() で黄色い (ブラウザ依存) ログも出せる。
console.time()
console.time(label); でタイマー開始、console.timeEnd(label) で経過時間表示
console.timeLog() で途中経過を表示可能
console.table()
配列やオブジェクトを渡すことによって Console に表形式のデータを表示させることができる
非標準とのこと
JavaScript Debugging Reference
Google Chrome 公式ドキュメント
デバッグするために与えられたコードで、コンソールとブレークポイントを使用する。
Debugging in Chrome
Google Chrome 公式ドキュメント
Chrome DevTools で JavaScript をデバッグする
ブレークポイントでコードを一時停止する
コード行のブレイクポイントだけでなく、DOM 変更のタイミングとか、XHR リクエストのタイミングとか、イベントリスナー、例外、関数、でも一時停止できることが説明されてる (使ったことなかったなぁ)
debugger;
ブラウザ機能のブレイクポイントではなく、明示的に JavaScript ソースに記述するときは、debugger; を呼び出す
非同期プログラミング: 13%
シナリオに基づき、非同期プログラミングの概念を適用する。
Promise とかですよね、めっちゃ苦手です...
Promise
Async/await
非同期 JavaScript
非同期プログラミングの一般的概念
非同期とは?から書いてあるのでわかりやすいです
JavaScript はシングルスレッドです
非同期関数
async で非同期関数を定義する。結果として Promise が返ってくる
非同期関数の中では await が使える。await では非同期関数の実行を待つことができる
Promise
以下の違いを明確にしておく
Promise.all()
Promise.race()
Promise.resolve()
then メソッドを使うプロミスチェーンも覚えておく
Promise.prototype.then()
then の実行順に注意 (リファレンスのサンプルコード参照)
then は async await で代替することも可能。代替の書き方に関するサンプル問題が Trailhead にあった
async function の中で、await が利用可能
code: 引用
Promise の状態は以下のいずれかとなります。
待機 pending: 初期状態。成功も失敗もしていません。
満足 fulfilled: 処理が成功して完了したことを意味します。
拒絶 rejected: 処理が失敗したことを意味します。
待機、満足、拒絶の 3 つの状態がある。 日本語訳あってるのか・・・?
Qiita 記事: 4歳娘「パパ、Promiseやasync/awaitって何?」〜Promise編〜
Qiita 記事: Promiseについて0から勉強してみた
Qiita 記事: Promiseの使い方、それに代わるasync/awaitの使い方
どうでもいい話ですが、"コールバック地獄" ってよく聞きますが、英語でも callback hell っていうんですね。
シナリオに基づき、イベントループとイベント監視を使用する、またはループの結果を判断する。
並行モデルとイベントループ
ここの図がわかりやすい
再帰関数はスタックに格納されるし、後述の setInterval 等はメッセージキューに格納される
スタックが空になってからキューが FIFO で実行される (実行順に注意)
Call stack (コールスタック)
WindowOrWorkerGlobalScope.setInterval()
非同期的に処理される
setInterval の第二引数の秒数ごとに第一引数の関数を実行、clearInterval で解除
WindowOrWorkerGlobalScope.setTimeout()
非同期的に処理される
setTimeout の第二引数の秒数後に第一引数の関数を実行
イベントリファレンス
JavaScript で監視できるイベントの一覧。対応するイベントリスナーや monitorEvents に追加することで監視が可能
Qiita 記事: 任意のイベントオブジェクトを Web ブラウザのコンソールに出力する monitorEvents が便利
サーバーサイド JAVASCRIPT: 8%
公式ドキュメント
公式ガイド (日本語)
シナリオと要件に基づき、Node.js のどの実装が適切なソリューションであるかを推測する。
HTTP
HTTPS
code: JavaScript
const https = require('https');
https.get('https://encrypted.google.com/', (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
}).on('error', (e) => {
console.error(e);
});
Events
File system
Path
シナリオと要件に基づき、Node.js のどの CLI コマンドが適切なソリューションであるかを推測する。
CLI Documentation
CLI Commands
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.
Command-line options
デバッグガイド
Debugger
Node.js のコアモジュールと特定のシナリオに基づき、Node.js のどの library/framework が適切なソリューションであるかを推測する。
Node.jsのモジュールの使い方
公式サイトではありませんが、コアモジュールが一覧で載ってます
About semantic versioning
npm semver calculator
^:同じメジャーバージョンの範囲内で、指定したマイナーバージョン、パッチバーション以上
~:同じメジャーバージョン、マイナーバージョンの範囲内で、指定したパッチバージョン以上
シナリオと要件に基づき、どの Node.js パッケージ管理ソリューションが最適であるかを区別する。
most depended upon packages
Lodash, Axios, Express, React ぐらいの概要、簡単な使い方を覚える
Lodash: 便利な関数をまとめて提供しているライブラリ
Axios: Promise ベースの HTTP クライアント
Express: Web アプリケーションフレームワーク
React: UI を作ることに特化したライブラリ
Chalk: ターミナル文字列のスタイリングをしてくれるパッケージ
Qiita 記事:【初心者向け】NPMとpackage.jsonを概念的に理解する
テスト: 7%
コードブロックと関連する単体テストを使用して、テストが効果的ではない部分を判断し、より効果的になるように変更する。
Jest とかもでるのかな・・・?(Trailhead くらいでしかやったことがない...)
この単元は 7% しかでないので捨てます。笑
参考記事:JavaScriptでも単体テストを導入しよう!ってかテストって何?
Trailhead: Test Your JavaScript
Trailhead: Unit Testing on the Lightning Platform
Write Tests for Your Lightning Components
Trailhead: Lightning Web コンポーネントのテスト
Qiita 記事:小さく始める JavaScript のテスト
受験後の感想
上でまとめたように自分では結構勉強したつもりでしたが、受験中はまったく手応えを感じませんでした。。。試験の提出ボタンを押す時はかなり緊張しましたが、無事に合格でした!
Server Side JavaScript(サーバーサイドJavaScript) の単元は 20% しかとれませんでした・・・まとめ中も思いましたが、これどうやって勉強したら良いかわからないですね。