A re-introduction to JavaScriptを読んだ

developer.mozilla.org

ざっくりとまとめてみた. 他の言語の経験がある人ならわかる所は省略した.

Types

JavaScriptには以下のような型がある.

  • Number
  • String
  • Boolean
  • Symbol (new in ES2015)
  • Object
  • null
  • undefined

Numberはいわゆるdouble型であるという点に注意.
JavaScriptにはint型はない(BigIntはある).

Variables

以下のように宣言できる. letとconstを用いるようにしよう.

let sum = 0;
for (let i = 1; i <= 10; i++) {
    // `i` is only visible in here
    sum += i;
}
// `i` is *not* visible out here
const PI = 3.14;
PI = 3; // will throw an error
var sum = 0;
for (var i = 1; i <= 10; i++) {
    sum += i;
}
// `i` *is* visible out here

Objects

JavaScriptのObjectはPythonの辞書のようなもの.

let obj = new Object(); // or obj = {};
obj.a = 1;
obj.b = 2;
console.log(obj.a + obj.b); // 3
console.log(obj['a']); // 1

関数もオブジェクトなので以下のようなことが出来る.

let obj = {
    a: 1,
    b: 2,
    sum: function () { return this.a + this.b; }
};
console.log(obj.sum()); // 3

Arrays

array.lengthがインデックスの最大値 + 1なのに注意.

let a = new Array();
a[0] = 'dog';
a[1] = 'cat';
console.log(a.length); // 2
a[100] = 'fox';
console.log(a.length); // 101

for ... ofループの例.

const a = [1, 2, 3, 4, 5];
let sum = 0;
for (const elem of a) {
    sum += elem;
}
console.log(sum); // 15;

Functions

大体普通. rest parameter operator, spread operatorの例だけ示す.

// rest parameter operator
function mySum(...array) {
    let sum = 0;
    for (const elem of array) {
        sum += elem;
    }
    return sum;
}
const a = [1, 2, 3];
console.log(mySum(1, 2, 3, 4, 5)); // 15
// spread operator
console.log(mySum(...a)); // 6

Custom Objects

new func();と呼び出すと, 新しいオブジェクトが作られ, funcの中のthisがそのオブジェクトを指すようになる.
これを利用するとコンストラクタが書ける.

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sayHello = function () {
        console.log(`Hello! My name is ${this.name}. I'm ${this.age} years old.`);
    }
}

let me = new Person('satoshi', 22);
me.sayHello(); // Hello! My name is satoshi. I'm 22 years old.

ちなみに関数内のthisが指すオブジェクトは, obj.func();と呼び出した場合はobjで, func();と呼び出した場合はundefined(ブラウザ上ならwindow?).
func.bind(), func.apply(), func.call()などを利用すればthisが指すオブジェクトを指定できる.
またarrow functionの場合, thisが指すオブジェクトは呼び出され方によらず, 宣言された場所で決まる.

function hello() {
    console.log(`Hi! My name is ${this.name}.`);
}

let me = { name: 'satoshi' };
me.hello = hello;
me.hello(); // Hi! My name is satoshi.
hello(); // Hi! My name is undefined.

また, Personのインスタンスは全てPerson.prototypeというオブジェクトを共有している.
prototypeにメソッドを追加することで, あとからメソッドを追加するなどトリッキーなことが出来る.

function sayBye() {
    console.log('Bye!');
}

let me = new Person('satoshi', 22);
Person.prototype.sayBye = sayBye;
me.sayBye();

Closures

元ページの例がわかりやすいのでそのまま. 関数が呼び出されるときにスコープオブジェクトが出来るが, 通常はreturnするときにGCにより消される.
しかし, 返り値になっている関数が元の関数のスコープオブジェクトを参照しているため, 消されない.

function makeAdder(a) {
    return function (b) {
        return a + b;
    }
}
const add5 = makeAdder(5);
const add20 = makeAdder(20);
console.log(add5(6)); // 11
console.log(add20(7)); // 27