技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Salesforce 開発者の JavaScript スキル(3)

trailhead.salesforce.com

あー来ちゃったよ日本語じゃないやつら(翻訳追いついてない奴ら)

Get Started with Modern JavaScript Development

モダンな JavaScript を始めよう。
ざっくり JavaScript の歴史を説明している。

重要なのは ES6 (ES2015 以降は年号)以降で一気に真価が加速した点だ。
モジュール化とかなんとかもこの辺から。

昨日が分からなくなったら ここ でどのブラウザが何に対応してるか分かる。
Trail では分からなくなったら Codepen で試そうとか言ってるけど、個人的に JSFiddle の方がシンプルで好きだ。

Explore New Syntax in JavaScript ES6

ES6 の新しい書き方を見ていこう。っても

var の様な関数スコープは昔からあるが、ブロック({ ... } で囲まれた区間のこと)をスコープに持つ const, let の紹介。
展開書式の紹介とかその程度

let numbers = [1, 2, 3, 4]; 
let [one, two, three, four] = numbers;
console.log(one);

とか

const APPLE = {
  type: 'red delicious',
  color: 'red',
  size: 'large'
}
const { type, color } = APPLE;
console.log(color);

とかアンパック構文(destructuring syntax)として使える。

ブロックスコープは管理が楽でええわー

Understand JavaScript Functions

JavaScript の関数を理解しよう

let result = (i,j) => i+j; 
console.log(result(2,3));  

こうじゃ!(関数はオブジェクトなので変数に突っ込めるで)というのと

let message = {
  hello : 'Hello',
  names : ['Sue', 'Joe'],
  showMessage: function() {
    this.names.forEach(function(name) {
      console.log(this.hello + ' ' + name);
    });
  }
}
message.showMessage();  

this 分かりづらいでしょ…( this.hello が undefined になってる)。

f:id:white-azalea:20211011222217p:plain

JavaScriptthis はその処理の呼び出し元を意味するので、

    this.names.forEach(function(name) {
      // この中の this は 「this.names」変数の意味になる
    });

なので

let message = {
  hello : 'Hello',
  names : ['Sue', 'Joe'],
  showMessage: function() {
    let self = this;
    this.names.forEach(function(name) {
      console.log(self.hello + ' ' + name);
    });
  }
}
message.showMessage();  

が正しい書式になる。しかし、クロージャ構文( => )を使うと、宣言したスコープの this を内部でもバインド(束縛)するので

let message = {
  hello : 'Hello',
  names : ['Sue', 'Joe'],
  showMessage: function() {
    this.names.forEach(name => {
      console.log(this.hello + ' ' + name);
    });
  }
}
message.showMessage() 

これは意図通りに動く。

f:id:white-azalea:20211011222237p:plain

因みに可変長引数はこんな感じで定義・アクセスできる。

function testFunc(arg1, ...multiple) {
    console.log(arg1);
    console.log(multiple[0]);
    console.log(multiple[1]);
}

Work with Classes

クラスを使ってみよう

つっても重要なのは大体サンプルコード通り。

class Animal {
  constructor(name) {
    this.name = name;
  }
    
  printName() {
    console.log(this.name);
  }
}

後はメソッドや getter, setter コンストラクタの書き方覚えましょう。

f:id:white-azalea:20211011222741p:plain

Organize Code with Modules

モジュールによってコードを組織化する

JQuery 時代だったら、グローバルスコープに jquery$ を定義したりしたけど、ES6 空は import / export ができる。

Java で import してた人にはなじみ深いんじゃないかな?
別ファイルに関数やクラスを定義したときに、

  • export クラス名or関数名 の構文で、他のJavaScript ファイルから呼び出しできるようになる
  • import { exportFuncName } from './path/to/file.js'; こんな感じで export した関数を取り込める

流石に複数ファイル取り込みとかは CodePen 使った方が良いかな…

Write Asynchronous JavaScript

非同期のJavaScriptを書こう

と言っても Promise 使おうという話。

function doSomething(msg){ 
  return new Promise((resolve, reject) => {
      setTimeout(
        () => {
          try {
            throw new Error('bad error');
            console.log(msg);
            resolve();
          } catch(e) {
            reject(e);
          }
        }, 
        1000);
    }) 
}
    
doSomething("1st Call")
  .then(() => doSomething("2nd Call"))
  .then(() => doSomething("3rd Call"))
  .catch(err => console.error(err.message));

そもそも再起呼び出しをサンプルにするのどーなんだと思わなくないが…
Promise は処理を遅延実行する仕組みだ。

そもそも、JavaScript の実行スタック(スレッド)は通常一つしか存在せず、タスクキューにやるべきイベントに積まれ、実行スタックが空ならキューより一つ取り出して処理する。
JavaScript の関数はすべてこれに従う。

Promise はスタック上でそのまま処理せず、必要な処理を一旦すべてキューに突っ込んでしまう。
その上でいつか適当なタイミングで非同期に実行されるというわけだ。

ES2016 以降は、async, await なんてものも加わり、Promise の処理が非常に書きやすくなった。

async function doSomethingManyTimes() {
  try {
    await doSomething("1st Call");
    await doSomething("2nd Call");
    await doSomething("3rd Call");
  } catch (e) {
    console.error(e.message);
  }
}
doSomethingManyTimes();  

‘async‘ は Promise 返すし、awaitasyncPromise を同期的に待つことができる。

Test Your JavaScript

JavaScript のテストをしよう

Jasmine というテストライブラリを使ってテストコードを書く

describe("A test suite is just a function", function() {
    it("This is a positive test", function() {
      expect(true).toBe(true);
    });
    it("This is a negative test", function() {
      expect(false).not.toBe(true);
    });
});  

テストは仕様書だ…の意識が強いライブラリで

describe 説明」で関数等に関する説明を、テストケースは it で定義し、中に expect 結果はこうなるべき…みたいな書き方をする。
テストコードを書いて、index.html を指定の書式で書けば実行してくれる。

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Jasmine files to load -->
    <link rel="shortcut icon" type="image/png" href="lib/jasmine-3.2.1/jasmine_favicon.png">
    <link rel="stylesheet" href="lib/jasmine-3.2.1/jasmine.css">
    <script src="lib/jasmine-3.2.1/jasmine.js"></script>
    <script src="lib/jasmine-3.2.1/jasmine-html.js"></script>
    <script src="lib/jasmine-3.2.1/boot.js"></script>
    
    <!-- JS Files to Test -->
    <script src="Parent.js"> </script>
    <script src="Child.js"> </script>
    
    <!-- Jasmine Test Suite -->
    <script src="JasmineTest.js"> </script>
    
</head>
<body>
    <h1> Jasmine Parent Child Testing Demo </h1>
</body>
</html>    

と、訳しながらバッチ取得。