【Salesforce】【資格】JavaScriptデベロッパー勉強メモ

JavaScriptデベロッパーの勉強メモです。合格したら受験体験記も書く予定です( * 'ω' * ) 

あくまでも個人のメモ書きなので信用しすぎてはいけません。
リファレンスを載せていますので、最新かつ正しい情報をご確認ください。

# 値プロパティ
単なる値を返す、プロパティもメソッドも持たない
undefined：値が代入されていない
NaN：非数
Infinity：正の無限大

NaNの判定にはisNaN()を使う
```JavaScript:
console.log(NaN === NaN);                 // false
console.log(isNaN('hello world'));        // true　値そのものor値の変換の結果 
console.log(Number.isNaN('hello world')); // false　値そのもの
```
undefinedの判定
```JavaScript:
var x;
console.log(x == undefined);            // false nullチェックのため
console.log(x === undefined);           // true ※xが宣言されていない場合はReferenceErrorになる
console.log(typeof x === 'undefined');  // true ※xが宣言されていない場合にReferenceErrorにならない
```
# 関数プロパティ
eval()：文字列として表現された JavaScript コードを評価する
```JavaScript:
console.log(eval('2 + 2'));                               // 4
console.log(eval(new String('2 + 2')));                   // 2 + 2　※String オブジェクトを返す
console.log(eval('2 + 2') === eval(new String('2 + 2'))); // false
```

isFinite()：有限数かどうかを判定する
```JavaScript:
console.log(isFinite(1000 / 0));  // false
console.log(isFinite(1000 / 1));  // true
```
isNaN()：NaN (非数) かどうかを判定する
```JavaScript:
console.log(isNaN('100F'));       // true
console.log(isNaN('0.0314E+2'));  // false
```
parseFloat()：浮動小数点値を返す
```JavaScript:
console.log(parseFloat(4.567));       // 4.567
console.log(parseFloat('abcdefgh'));  // NaN
```
parseInt()：基数の整数値を返す
```JavaScript:
console.log(parseInt('0xF', 16));  // 15
console.log(parseInt('321', 2));   // NaN
```
# Objectクラス
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object

assign()：1 個以上のソースオブジェクトから、自身の列挙可能なプロパティの値をすべてターゲットオブジェクトにコピーする
```JavaScript:
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
Object.assign(target, source);
console.log(target);// { a: 1, b: 4, c: 5 }
```
create()：既存のオブジェクトを新しく生成されるオブジェクトのプロトタイプとして使用する
```
const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};
const me = Object.create(person);
```

defineProperty()：プロパティをオブジェクトに追加
```JavaScript:
const object1 = {};
Object.defineProperty(object1, 'property1', {value: 42, writable: false});
console.log(object1.property1);// 42
```
is()：二つの値が同じ値であるかどうかを比較する
```JavaScript:
console.log(Object.is('foo', 'foo'));     // true
console.log(Object.is('foo', 'bar'));     // false
console.log(Object.is([], []));           // false
console.log(Object.is(null, null));       // true

var foo = { a: 1 };
var bar = { a: 1 };
console.log(Object.is(foo, bar));         // false

console.log(Object.is(0, -0));            // false
console.log(Object.is(-0, -0));           // true
console.log(Object.is(NaN, 0/0));         // true
```
keys()：与えられたオブジェクト自身の列挙可能な文字列プロパティの名前の配列を返す
values()：与えられたオブジェクト自身の列挙可能な文字列プロパティの値の配列を返す
```JavaScript:
const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};
console.log(Object.keys(object1));// [ 'a', 'b', 'c' ]
console.log(Object.values(object1));// [ 'somestring', 42, false ]
```
preventExtensions()とseal()とfreeze()
| 種類 | 追加 | 削除 | 値変更 |
|:-:|:-:|:-:|:-:|
|preventExtensions()|×|○|○|
|seal()|×|×|○|
|freeze()|×|×|×|



# NumberクラスとDateクラス
```JavaScript:
console.log(Number("abc"));            // NaN
console.log(new Number('200') == 200); // true Number(文字列)は数値への変換
console.log(new Number(200) === 200);  // false new Number(数値)はNumber型の初期化

const pi = 3.1415326;
console.log(typeof(pi));//number
```
```JavaScript:
console.log(Date());                                 // 現在日時の文字列表現
console.log(new Date().toString());                  // 現在日時の文字列表現
console.log(new Date());                             // 現在日時
console.log(new Date('December 17, 2021 03:24:00')); // 日時
```
# Stringクラス
```JavaScript:
console.log(typeof String('Hello world'));     // string
console.log(typeof new String('Hello world')); // object

const str = 'Mozilla';
console.log(str.substr(1, 2));    //oz　開始位置、文字数
console.log(str.substring(1, 3)); //oz　開始位置、終了位置
console.log(str.slice(1, 2));    //oz　開始位置、数 

let val1 = 10;
let val2 = 20;
console.log(String(val1).concat(val2));          // 1020
console.log(val1.toString() + val2.toString());  // 1020

const paragraph = 'abcDefGHijk';
const regex = /[A-Z]/g;
console.log(paragraph.match(regex));// [ 'D', 'G', 'H' ]
console.log(paragraph.search(regex));// 3

console.log('  Hello world!  '.trim());       // 'Hello world!'
console.log('  Hello world!  '.trimEnd());    // '  Hello world!'
console.log('  Hello world!  '.trimStart());  // 'Hello world!  '

const str1 = 'Saturday night plans';
console.log(str1.startsWith('Sat'));    // true
console.log(str1.startsWith('Sat', 3)); // false 第二引数は開始位置

const sentence = 'abcDefGHijk';
console.log(sentence.toLowerCase()); // abcdefghijk
console.log(sentence.toUpperCase()); // ABCDEFGHIJK
```
# String　→　Object

```JavaScript:
const json = '{"result":true, "count":42}';
const obj = JSON.parse(json);
console.log(obj.count);// 42
console.log(obj.result);// true

JSON.parse(' " foo " ');//ちなみにこれはOK！
```

# String　と　Number

```JavaScript:
console.log(('6' / 2)); // 3
console.log(('6' * 2)); // 12
console.log(('6' + 2)); // 62 文字列
```

# Arrayクラス

```JavaScript:
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));      // [ 'camel', 'duck', 'elephant' ]
console.log(animals.slice(2, 4));   // [ 'camel', 'duck' ]
console.log(animals);               // [ 'ant', 'bison', 'camel', 'duck', 'elephant' ] 要素は削除されない

console.log(animals.splice(4));     // [ 'duck', 'elephant' ]
console.log(animals);               // [ 'ant', 'bison', 'camel', 'duck' ]　要素は削除される
console.log(animals.splice(1, 1));  // [ 'camel', 'duck' ]
console.log(animals);               // [ 'ant', 'camel', 'duck' ]　　　　　　要素は削除される

console.log(animals.splice(2, 0, 'pig')); // []
console.log(animals);                     // [ 'ant', 'camel', 'pig', 'duck' ] 要素が追加される

const array1 = [1, 2, 3, 4];
const sumWithInitial = array1.reduce((previousValue, currentValue) => previousValue + currentValue,0);
console.log(sumWithInitial); // 10

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result); // [ 'exuberant', 'destruction', 'present' ]

```
# Promise
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

https://qiita.com/cheez921/items/41b744e4e002b966391a

ステータスは３つ
　pending: 未解決 (処理が終わるのを待っている状態)
　fulfilled: 解決済み (処理が終わり、無事成功した状態)　　→then
　rejected: 拒否 (処理が失敗に終わってしまった状態)　　　→catch
　※settledというステータスはない
```JavaScript:
const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value); // two
});
```

# 関数
https://qiita.com/may88seiji/items/4a49c7c78b55d75d693b

https://tcd-theme.com/2021/06/javascript-difference-arrowfunction-otherfunctions.html?gclid=Cj0KCQjwsrWZBhC4ARIsAGGUJuqEVmYRMXxt_BPig4k2ffaPslgZErGJ8QeZEOMI7de9WF1uQq_OkScaAuznEALw_wcB

```JavaScript:
// 従来の関数
function (a, b){
  return a + b + 100;
}
// アロー関数
(a, b) => a + b + 100;

// 従来の関数 (引数なし)
let a = 4;
let b = 2;
function (){
  return a + b + 100;
}

// アロー関数 (引数なし)
let a = 4;
let b = 2;
() => a + b + 100;
```
```JavaScript:
// 従来の関数
const addBy = function(num1){
    return function(num2){
        return num1 + num2;
    }
}
const addByEight = addBy(8);
const sum = addByEight(50);

// アロー関数
const addBY = (num1) => (num2) => num1 + num2;
```

アロー関数
宣言 変数名 = (引数) => {処理（返り値）}
```JavaScript:
const materials = [
  'Hydrogen',
  'Helium'
];
let res = materials.map(material => material.length)
console.log(res);//[ 8, 6 ]
```

関数
function 関数名 (引数) {処理}

関数式
宣言 変数名 = function 関数名() { 処理（返り値）}
宣言 変数名 = function () { 処理（返り値）}　


# 例外のthrow
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/throw

```JavaScript:
throw 'Error2'; 
throw new Error('Required');
```


カスタム例外
```JavaScript:
function MyException(message) {
   this.message = message;
   this.name = 'MyException';
}
```

# var, let, const
`var`   スコープが関数内
`let`   スコープがブロック内
`const` スコープがブロック内　初期化必須、代入不可

```JavaScript:
function myFunction(){
   let a = 5;
}
myFunction();
console.log(a);// ここでおちる
```

```JavaScript:
function myFunction(){
   var a = 5;
}
myFunction();
console.log(a);// ここでおちる
```
```JavaScript:
function myFunction(){
   "use strict";// Strictモード
   a = 5;// ここでおちる
}
myFunction();
console.log(a);
```
```JavaScript:
function myFunction(){
   a = 5;
}
myFunction();
console.log(a);// 5、落ちない
```

```JavaScript:
if(true) {
    var a = 5;
}
console.log(a); // 5、落ちない
```

# export
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export

exportの種類は２つ
　①名前付きエクスポート (モジュールごとに 0 以上のエクスポート)
```JavaScript:
export { myFunction, myVariable };
export let myVariable = Math.sqrt(2);
```
　②デフォルトエクスポート (モジュールごとに 1 つのエクスポート)
```JavaScript:
export { myFunction as default };
export default function () { ... };
```
例
```JavaScript:
//Utils.js　①foo、barの関数式を作成しexportする
const foo = () => { return 'foo' ; }
const bar = () => { return 'bar' ; }
export { bar, foo }
```
```JavaScript:
//Utils.js　②defaultクラスにfoo()bar()を定義する
export default class {
    foo() { return 'foo' ; }
    bar() { return 'bar' ; }
}
```
# import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

https://qiita.com/koeri3/items/314ac7b9b73fc8c80a2d

importの種類　※importされたモジュールはすべてStrictモードになる
　・すべてをインポートする
```JavaScript:
import * as myModule from '/modules/my-module.js';
```
　・１つ以上をインポートする
```JavaScript:
import {myExport} from '/modules/my-module.js';
import {foo, bar} from '/modules/my-module.js';
```
　・別名をつけてインポートする
```JavaScript:
import {reallyReallyLongModuleExportName as shortName} from '/modules/my-module.js';
```
　・デフォルトをインポートする
```JavaScript:
import myDefault from '/modules/my-module.js';
```
　・デフォルトに別名をつけてインポートする
```JavaScript:
import myDefault, * as myModule from '/modules/my-module.js';
```

# Consoleクラス
https://developer.mozilla.org/ja/docs/Web/API/console

console.assert()　アサーション
console.clear()　コンソールをクリア
console.count()　この行が呼び出された回数をログ出力
console.debug()　ログレベルが debug のコンソールへメッセージを出力
console.dir()　　プロパティの、対話型リストを表示
console.group()　以降のすべての出力を字下げ、groupEnd()でえ戻す 
console.groupCollapsed() グループが折りたたまれた状態で作られる
console.table()　表形式のデータを表を使用して表示
console.time()　タイマーを開始ページあたり最大 10,000 個
console.timeEnd()　タイマーを停止して、時間を秒単位でログに出力
console.timeLog()　タイマーの値を出力

console.info()　メッセージタイプのログ情報を出力
console.log()　一般タイプのログ情報を出力
console.warn()　警告メッセージを出力
console.error()　エラーメッセージを出力

# Historyインターフェース
https://developer.mozilla.org/ja/docs/Web/API/History

ブラウザーのセッション履歴を操作できる
length：セッション履歴の要素数
back()：非同期、ユーザーがブラウザーの戻るボタンをクリックしたときと同じ（セッション履歴の一つ前のページへ移動する）
forward()：非同期、ユーザーがブラウザーの次へボタンをクリックしたときと同じ、 history.go(1)
go()：非同期、セッション履歴上で、現在のページからの相対位置で識別されるページを読み出す
　　　引数無しまたは0の場合は現在のページを再読み込みする
pushState()：指定されたデータを指定されたタイトルでセッション履歴に追加する

# setTimeout()
```JavaScript:
setTimeout(() => {console.log("first")}, 500);
let timerId = setTimeout(() => {console.log("second")}, 300);
clearTimeout(timerId);
setTimeout(() => {console.log("third")}, 100);
// 結果は
// third
// first
```
※setTimeout()自体は非同期関数＝待ってもらえない

# setInterval()
```JavaScript
var intervalID = setInterval(myCallback, 1000, 'Parameter 1', 'Parameter 2'); 
function myCallback(a, b)
{
 console.log(a);
 console.log(b);
}
```

# extends
```JavaScript:
class Square extends Polygon {
    constructor(length) {
      super(length, length);// thisを使う前に super() を呼び出さないとエラー
      this.name = 'Square';
    }
    get area() {
      return this.height * this.width;
    }
}
```

# prototypeの使用
```JavaScript:
function GameConsole (name) {
 this.name = name;
}
GameConsole.prototype.load = function(gamename) {// prototypeでload()を追加
 console.log( ` ${this.name} is loading a game : ${gamename} ...`);
}
function Console16bit (name) {
 GameConsole.call(this, name);
}
Console16bit.prototype = Object.create(GameConsole.prototype) ;// GameConsoleからConsole16bitをcreate
Console16bit.prototype.load = function(gamename) {// loadのオーバーライド
console.log( ` ${this.name} is loading a cartridge game : ${gamename} ...`);
}
const console16bit = new Console16bit(' SNEGeneziz ');
console16bit.load(' Super Nonic 3x Force ');
```

# 値渡しと参照渡し
https://qiita.com/migi/items/3417c2de685c368faab1
https://qiita.com/yuta0801/items/f8690a6e129c594de5fb
```JavaScript:
var a = { val: 10 }
var b = a
a.val = 100
console.log(b) // 100　値は値渡し
```
```JavaScript:
var a = { val: 10 }
var b = a
a = { val: 100 }
console.log(b) // 10 　プロパティは参照渡し
```
```JavaScript:
function changeValue(param) {
    param = 5;
}
let a = 10;
let b = a;
changeValue(b);
const result = a + " - " + b;//10 - 10　引数は値渡し
```




# localStorageの読み書き
```JavaScript:
// 書き込み
localStorage.setItem('myCat', 'Tom');
//　読み込み
let cat = localStorage.getItem("myCat");
// 削除
localStorage.removeItem("myCat");
```
オブジェクトの場合は、JSON.stringify(),JSON.parse()を使用することに注意！
```JavaScript:
let object = {
    key1: "name1",
    key2: "name2"
};

// 書き込み ※JavaScriptオブジェクト -> JSON文字列に変換
localStorage.setItem("myObject", JSON.stringify(object));
// 読み込み ※JSON文字列 -> JavaScriptオブジェクトに変換
JSON.parse(localStorage.setItem("myObject"));
// 削除 ※変わらず
localStorage.removeItem("myObject");
```

# Node.js について
https://zenn.dev/antez/articles/a9d9d12178b7b2

https://www.sejuku.net/blog/87186

https://blog.kkty.jp/entry/2019/01/09/214947

・path、httpなどのコアモジュールが提供されている
・npmはNode Package Managerの略でプライベートパッケージ、プライベートレジストリを利用できる
・ノンブロッキング機能がある（ファイル読込を別スレッドで行うため、メインスレッドは処理を続けることができる）
・`__dirname`　現在のディレクトリのパスを示す変数
・`__filename`　現在のモジュールの絶対パスを示す変数
・`node inspect ファイル名`  デバッグするときのコマンド　
　※`repl`コマンドを使うとデバッグ途中で変数やオブジェクトの値をその場で調べることができる

# Node.jsのサーバ実装
```JavaScript:
//httpオブジェクトのロード
var http = require('http');
//Serverオブジェクトの作成
var server = http.createServer();
server.on('request', doRequest);
server.listen(process.env.PORT, process.env.IP);
console.log('Server running!');
 
// リクエストの処理
function doRequest(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write('Hello World\n');
    res.end();
}
```

# その他
・プロパティの参照
```JavaScript:
const userInfo = {
    "id" : "user-01",
    "email" : "user01@user.demo",
};
console.log(userInfo.email);
console.log(userInfo["email"]); // userInfo.get("email")はない
```

・Document.querySelector()：指定されたセレクター群に一致する、文書内の最初の Element を返す
```html:
<div id="main">
  <ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
  </ul>
</div>
```
```JavaScript:
document.querySelector('$main li:nth-child(2)'),innerHTML = 'B→F';
```

・Cookie ：WEBサイトを閲覧したときに、訪問者が訪れたサイトや入力したデータ、利用環境などの情報が記録されたデータ
・IndexedDB API：ファイルや blob を含む大量の構造化データをクライアント側で保存するための低レベル API 
・IIFE：即時実行関数式、定義されるとすぐに実行される  `(function () {文})();`
・strictモードでエラーになるパターン
　　- 変数宣言なしの変数に値を入れた
　　- with文を使用した
　　- 予約語を変数名に使用した
・セマンティックバージョニング
　　v0.x.x：開発中
　　v★.x.x：後方互換性なしAPIの変更
　　vx.★.x：後方互換性ありAPIの変更
　　vx.x.★：APIや依存関係に影響を与えない変更
　　vx.x.x-beta：ベータ版などリリース前
・Falsy（偽値）：　false、null、0、-0、0n、””、undefined、NaN
・フレームワーク
　　Angular：Googleが開発、Webアプリケーション開発に必要なほとんどの機能をサポート
　　React：Facebookが開発、ページを常に更新できる、WebサイトのUIパーツを構築するために使われる
　　jQuery：JavaScriptのコードを容易に記述するために開発された、短いコードで高性能なUIを形にすることが可能
　　Vue：WebアプリケーションのUIを構築できる、小規模なアプリケーション開発などに向いているフレームワーク
　　Express：Node.jsを活用したWebアプリ開発、ルーティング・クッキー・RESTfulなインターフェースを装備
　　Koa：expressの開発チームによって設計された軽量フレームワーク、リクエストやレスポンスなど限定的な処理
・検索のデバウンス機能実装：
　　ネットワーク・リクエストのプロパティであるdebounceがtrueに設定されていることを確認する
　　検索文字列が変更されたら、setTimeout 以内にリクエストをエンキューする
　　既存のsetTimeoutがあり、検索文字列が変更された場合、既存のsetTimeoutを終了させ、新しいsetTimeoutを待ち行列に入れないようにする
・False negative　NGだけどOKと判定してしまう
・False positive　OKだけどNGと判定してしまう

```JavaScript:
function Monster(){this.name ='hello'};
const z = Monster();// newしてない
```
上記コードを実行するとWindow.nameは'hello'に割り当てられ、変数zは未定義のままとなる

```JavaScript:
let x = null;
console.log(typeof x);// object
```
nullのタイプはobject

```JavaScript:
account.Style.display = ' block '; // 表示
account.Style.display = ' none ';  // 非表示
```


# お世話になった過去問
https://qiita.com/Davoi/items/c6fe30c135f10e24128d

# 各試験の体験記まとめ

https://qiita.com/piepie1231/items/78a0dd6bdfa2c64568cd