JSの特徴
- プロトタイプベースのオブジェクト指向
- リテラル表記の表現力
- 関数型プログラミングであること
- CやJavaに似た構文
- インタプリタ言語
プロトタイプベースのオブジェクト指向
オブジェクト指向プログラミング言語(C++やJavaなど)と異なり、クラスがJSには存在しない。そのかわりに、クラスのような機能を実装するために、
- prototype
- new演算子
- this
が用意されている。これらを使い、クラスのような「プロパティとメソッド」をひとまとめにしたものを定義することができる。
リテラル表記とは
- リテラルとは、ソースコードに書いた文字とか数字のこと
- var age = 18; の18のようにべた書いた文字のこと
関数型プログラミングとは
- 関数をオブジェクトとして扱うことができること。
- 関数リテラルが存在することで関数プログラミングをサポートしている。
インタプリタ言語
コンパイル型と対のもので、実行環境でコードを直接動かすことができるもの。
変数、定数、関数について
記法
//再宣言不可能な定数を宣言
const a = 1;
//宣言だけすることは不可能なので注意
const a; //エラーがでる
//再宣言不可能な変数を宣言
let a
//変数の宣言(今はもう必要ない)
var a;
//varの省略(暗黙の宣言)
//たとえスコープ内にいても強制的にグローバル変数になる。
a;
let constのブロックスコープ
//ブロック文はスコープがないのでアクセスできる
if(true) {
var test = 'hoge';
}
console.log(test);
//hoge
if(true) {
const test = 'hoge';
let test2 = 'hoge2';
}
console.log(test);
console.log(test2);
//"test is not defined"
//"test2 is not defined"
変数の巻き上げ
var a = 'hello';
function sing(){
console.log(a);
var a = 'world';
console.log(a);
}
sing();
//undefiend
//world
関数スコープをもち、変数は関数内で宣言されたものを参照する。
変数aは以下のように宣言されたようになる。
var a = 'hello';
function sing(){
var a;
console.log(a);
a = 'world';
console.log(a);
}
sing();
関数内で宣言された変数は、いかなる場所で宣言してもその関数の先頭で宣言されたものと同じ動作をする。このような振る舞いを巻き上げ(hosting)という.
ただし、巻き上げが起きるのは宣言部分だけであり、中身は代入されない。
そのため、undefined値が返る。
このときaも宣言されていないことになれば、reference errorが返るはずである。
これは letでもconstでも生じる。
関数
- 関数とは一連の手続きをまとめて外部から呼び出せる仕組みのこと。引数を渡せ、関数は値を返す
- 関数本体を宣言しただけではだめで、関数自体を呼ぶ必要がある
- 関数宣言文と関数リテラル式がある
- 関数リテラル式と関数呼び出し式は別物である
- 式とは演算子とオペランド(2+3であれば、2や3のこと)をつなげたもの
//基本の型
function 関数名(引数、引数...){
関数本体
}
//関数宣言文
function sum(a, b) {
return Number(a) + Number(b);
}
//関数呼び出し式
sum(3, 5);
//8
//関数リテラル式
function (a, b) {
return Number(a) + Number(b);
}
//関数リテラル式は式なので式の中にかけるのが特徴
const sum = function(a, b) {
return Number(a) + Number(b);
}
//値はsumに格納される
console.log(sum);
//8
関数宣言文の特徴で関数の巻き上げ(hosting)が生じる
sum(3, 5);
//関数宣言文
function sum(a, b) {
return Number(a) + Number(b);
}
//8
//どの場所で宣言しても最初に宣言されたものとして考えられる
無名関数
- 関数リテラル式は関数名がないので無名関数としても考えられる
- 無名関数はコールバック関数として使われることが多い。
const sum = function(a, b) {
return Number(a) + Number(b);
}
function hoge(a) {
console.log(a);
}
hoge(sum(3, 5));
//8
//形としては以下のようになっている
//関数の中に無名関数が引数として入る
hoge(function(3, 5){
consolelog(return Number(3) + Number(5);
});
即時関数
- 一回しか読み込まれない処理をグローバルスコープを汚染せずに実行する
- 関数内スコープをもつので、グローバルスコープを汚染しない
- ES6においては、let,constがブロックスコープをもつので必要ない事が多い
//関数リテラル式を()で囲い、次の()で引数を指定する。
(function(a, b) {
return Number(a) + Number(b)
})(3, 5);
//8
オブジェクト
- 名前と値の集合体のこと
- 名前と値のセットをプロパティと呼ぶので、プロパティの集合体ともいえる
- JSでは関数もオブジェクトと捉えることができる
- オブジェクトの生成はオブジェクトリテラル式で行う
//オブジェクトリテラル式の基本
{プロパティ名:プロパティ値,プロパティ名:プロパティ値,プロパティ名:プロパティ値,...}
//例
//プロパティ名は識別子、数値、文字列が入る
const obj = {x:2, y:3};
const obj2 = {1:2, 3:3};
const obj3 = {'x':2, 'y':3};
//オブジェクトや関数もいれることができる
const obj4 = {pos:{x:2, y:3}};
const obj5 = {sum:function(a, b) {return Number(a) + Number(b)}};
### プロパティアクセス * ドット演算子やブラケット演算子で呼び出すことができる * ドット演算子で行う関数呼び出しを、メソッドと呼ぶ
const obj = {x:2, y:3};
const obj2 = {1:2, 3:3};
const obj3 = {'x':2, 'y':3};
const obj4 = {pos:{x:2, y:3}};
const obj5 = {sum:function(a, b) {return Number(a) + Number(b)}};
console.log(obj.x) //=> 2
console.log(obj['x']) //=> 2
console.log(obj4.pos) //=> {x:2, y:3}
console.log(obj5.sum(3, 5)) // => 8
//新規追加することもできる
obj5.z = function hoge(a) {console.log(a)};
console.log(obj.z('hello')) // => hello
オブジェクト生成のためのnew式
- オブジェクトを生成するための式
- JSではnew式のあとに書くものは関数名である
- インスタンス(実体)を作成するための関数(コンストラクタ)
- 実質、関数名をクラスと呼んでも問題はない
クラスは設計図、インスタンスは設計図をもとに作成した実体。コンストラクタは設計図から実体を生み出すための関数だと理解する。作成された実体をインスタンスオブジェクトとも呼ぶ。インスタンスオブジェクトはそれぞれ違うものになる。設計図をもとに作られたドラえもんは、一人ひとり別物。
//Objectが関数名 objがインスタンス
const obj = new Object();
const obj2 = new Object();
obj == obj2; // => false
オブジェクトに関してもプロパティアクセスは2種
1. **クラス(Object)**に関してのプロパティアクセス
2. obj (クラスから生成されたインスタンスオブジェクト)に対してのプロパティアクセス
//1番はクラスに対してのメソッド
String.fromCharCode();
//2番はStringクラスのインスタンスに対してのメソッド
//インスタンスstrに対して
var str = "こんにちは、";
var name = "鈴木さん";
str = str.concat(name, "。今日はいい天気ですね。");
console.log(str); //こんにちは、鈴木さん。今日はいい天気ですね。
文字列や配列に対してメソッドが使える理由は、クラスのインスタンスオブジェクトに対してプロパティアクセスしているからで、str自体がプロパティとして関数を持っている必要はない。
配列
- 配列は順序を持った値の集まりを表現する
- リテラル表記で生成する。
- 生成された配列は、Arrayクラスのインスタンスとして生成される
- 配列はそれぞれに**添え字(インデックス)**をもち、それによってアクセスが可能
//配列の生成
const arr = [1, 100, 50];
//配列へのアクセス
console.log(arr[0])
// 1
console.log(arr[1])
//100