Javascript学習1

変数の宣言について

再宣言、再代入に関して

変数宣言 再代入 再宣言
const x x
let x o
var o o

再宣言のできるvar潜在的なバグを生みやすい為、使用しないこと!!

> var a = 1;
> a = 2
> var a = 2;  // 再代入が可能!!
> a
2
> var a = 3; // 再宣言が可能!!
> a
3

> let b = 1;
> b = 2; // 再代入が可能!!
2
> b
2
> var b = 3; // 再宣言は不可!!
Uncaught SyntaxError: Identifier 'b' has already been declared

> const c = 1;
> c = 2; // 再代入不可!!
Uncaught TypeError: Assignment to constant variable.
> const c = 3; // 再宣言不可!!
Uncaught SyntaxError: Identifier 'c' has already been declared

巻き上げ(Hosting)について

var で宣言した変数はコードが実行される前に生成される。これを巻き上げ`という。
下記の実行結果のように宣言する前に代入が可能。 初学者がバグを生む理由に繋がる。

// foo.js
a = 100;
console.log(a);
let a;


$node foo.js
100

let, const だとReference Errorが発生する。

// foo.js
a = 100;
console.log(a);
var a;


$node foo.js
ReferenceError: Cannot access 'a' before initialization

スコープについて(一番、厄介)

var のスコープは関数単位である!! また、関数の外で宣言されるとグローバルになる。

// foo.js
var x = 100; // 関数の外なので、グローバル変数になる!!

if (true) {
  var x = 200;
  var y = 300;  // 関数の外なので、グローバル変数になる!!
  console.log(x);
}

console.log(x);
console.log(y);

///////////////////////////////
$ node foo.js
200
200
300

Rubyを始めとする大多数の言語の変数のスコープはブロック単位となる。
これはlet, constを使用すると同じ挙動になる。

// foo.js
let x = 100;

if (true) {
  let x = 200;   // スコープはブロック内
  let y = 300;  // スコープはブロック内
  console.log(x); 
}

console.log(x);
console.log(y); // y は宣言されていないのでerror

//////////////////////////////
200
100
ReferenceError: y is not defined

結論

constを第一優先で使用し、どうしても再代入が必要な場合はletを使用する。

参考

var - JavaScript | MDN

データ型

JavascriptRubyと同じで動的型付け言語。代入される型によって変数の型が変更される。
データ型はプリミティブ型オブジェクト型に大別される。

> let x = 1
undefined
> typeof x
'number'
> x = 'a'
'a'
> typeof x
'string'

プリミティブ型

JavaScriptにおいてオブジェクトではなく、メソッドを持たないデータのこと。

Primitive (プリミティブ) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN

Boolean

true, false の2つの値を持つ。

`0, -0, null, false, NaN, undefined, "" 'はfalseの初期値を持つ。

Boolean - JavaScript | MDN

Null

null という値は、意図的にオブジェクトの値が存在しないことを表す。

null - JavaScript | MDN

Number

Rubyなどでは違い、整数も少数も同じ型として扱われる。
それ以外にも+Infinity, -Infinity, NaNの3つの値がある。

  • NaN(Not a Number)について 数値として解釈できない場合などに返される値。

NaN - JavaScript | MDN

BigInt

Number型で扱えきれない大きな数値を扱うデータ型。(Number型の最大値は約9千兆...)。
Number型と互換性がない為、相互に計算ができない!!

String

文字列を扱うためのデータ型。

Symbol

オブジェクトのキーとして使用することができる。
動的に無名の一意の値を生み出す。

Symbol - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN

Undefined

値が代入されていない変数の値はundefinedになる!

undefined - JavaScript | MDN

オブジェクト型

JavaScript ではnull, undefinedを除くプリミティブ型には、それらの値を抱合するラッパーオブジェクトが存在する。 注意することしては同じ値を表現する者であっても、プリミティブ型とラッパーオブジェクトは等価とはならない。

> const x = 'foo';
> const y = new String('foo');
> x
'foo'
> y
[String: 'foo']
> x === y
false
> x === y.valueOf() // valueOf()で返す値がプリミティブ値に対応する
true

プリミティブ値に対してメソッドを呼び出せるのは、「対応するラッパーオブジェクトに自動変換される」という仕様のため。

>'apple orange'.replace('orange', 'banana')
// 対応するラッパーオブジェクトに変換され、実行される
> (new String('apple orange')).replace('orange', 'banana')
'apple banana'