javascript基本メモ

#初めに
JavaScriptをもう一度基礎から勉強した基本構文メモです。
自分用なので誤字脱字があるかもしれません。
今後色々追加していく予定です。


##変数
変数とは繰り返し使う値を格納しておく入れ物
変数を定義することを「変数を宣言する」と言う

~~~JavaScript

//変数の宣言
let a = 0;
const b = 0;
var c = 2;

//出力
console.log(a);
console.log(b);

//letかconstを使う
let(ES6~)
const(ES6~)
var(非推奨)


/**
 *const,let等の変数宣言
 */
 
//======================================let
let val2 = "let変数";
console.log(val2);

//letは上書きが可能
val2 = "let変数を上書き";
console.log(val2);

//letは再宣言不可能
let val2 = "let変数を再宣言";
>>Identifier 'val2' has already been declared 

//======================================const
const val3 = "const変数";
console.log(val3);

//const変数は上書き不可
val3 = "const変数を上書き";
>>"val3" is read-only

//const変数は再宣言不可
const val3 = "const変数を再宣言";
>>Identifier 'val3' has already been declared

//constで定義したオブジェクトはプロパティの変更が可能
//(オブジェクトで定義する場合にはconstで定義)
const val4 = {
  name: "cherry",
  age: 8
}
val4.name = "mee";
console.log(val4);
>>{name: "mee", age: 8}

//constで定義した配列も変更可能
const val5 = ['dog', 'cat'];
val5[0] = "bird";
val5.push("monkey");
console.log(val5);
>>(3) ["bird", "cat", "monkey"]

//非推奨
 var val1 = "val変数";
 console.log(val1);

 //var 変数は上書き可能
 val1 = "var変数は上書き可能";
 console.log(val1);

 //var　は変数は再宣言可能
 var val1 = "val変数を再宣言";
 console.log(val1);
~~~

##テンプレート文字列
~~~JavaScript
/**
 * テンプレート文字列
 */

 const name = "cherry";
 const age = 8;

 //従来の方法
 const massege = "私の名前"　+ name + "歳は"　+ age;
 console.log(massege);

 //テンプレート文字列を用いた方法
 const massege2 = `私の名前${name}で歳は${age}`;
 console.log(massege2);

~~~


##関数

関数とは一連の手続き（処理）を実行する文の集まり
関数に渡す変数が「引数」
関数の呼び出し元に返す値が「戻り値」

~~~JavaScript
//関数の宣言
function fn(引数１, 引数2){
  return 戻り値;
}

//関数の呼び出し
fn(実引数１, 実引数2);

~~~

##オブジェクト
オブジェクトとは名前（プロパティまたはキー）と値（バリュー）をペアで管理するもの

名前：値
名前：関数名
名前：オブジェクト
 
~~~JavaScript
let obj = {
  property: 'hello',
  property: function(){
    },
  property: {
    d: 'Bye'
    }
}

//プロパティへのアクセス方法
//ドット記法
obj.name

//ブランケット記法
obj['name']

//例
let obj = {
    prop1: 'value1',
    prop2: 'value2',
    prop3: function(){
      console.log('value3')
    },
    prop4: {
      prop5: 'value5'
    }
}

obj.prop3();
console.log(obj.prop4);
console.log(obj.prop4.prop5);

//値を追加することもできる
obj.prop6 = 'value6';
console.log(obj['prop6'])
~~~


##JavaScriptとは
・ECMAScriptの仕様に基づいて実装されているプログラミング言語
・環境によって使える機能が変わってくる
・universal JavaScript は様々な環境で動くように作られたJavaScript 
・ブラウザとJSエンジンで違うが一番シェアがあるのはV8
・JavaScriptからweb APIsを通してブラウザを操作する
・APIとはアプリケーションプログラミングインターフェースの略でソースから別のアプリケーションを動かす仕組みのこと

##実行環境

###コードが実行されるまで
・JSエンジンによって生成されるコード内のどこからでもアクセスできるオブジェクト
・JavaScript実行前にはグローバルオブジェクトとthisが準備される
・ブラウザのグローバルオブジェクトはwindowオブジェクトとなる

##実行コンテキスト
コードを実行する際の文脈・状況
(コードが実行されているとき、どのような状況で実行されているか)

#####グローバルコンテキスト（ファイル直下で実行するもの）
・実行中のコンテキスト内の変数・関数
・グローバルオブジェクト
・this
が使用可能

#####関数コンテキスト（関数内で実行されるもの）
・実行中のコンテキスト内の変数・関数
・argument
・super
・this
・外部変数

##コールスタック
Javascriptエンジンが保持している為、実行中のコードがたどってきたコンテキストをたしかめることができる
このようなスタックの仕組みを「後入れ先だし」LIFO（Last In ,First Out）という

ホイスティング（宣言の巻き上げとも言う）
コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーに配置すること

~~~JavaScript
//実行される
a();

function a() {
    console.log('hogehoge')
}

//変数の場合

var b = 0;
console.log(b);//出力される


console.log(c);//出力されない
var c = 0;

~~~


関数宣言の仕方
関数と関数式では挙動の違いがある

~~~JavaScript
//これだとaを出力しようとするとエラーがでる
a();

const a = function(){
    console.log(c);
    let c = 1;
}

~~~

##スコープ
スコープとは実行中のコードから値と式が参照できる範囲

windowオブジェクト＝グローバルスコープ
一般的にはスクリプトスコープもグローバルスコープと呼ばれる

###関数スコープとブロックスコープ
関数宣言はブロックスコープは無視されてしまう

~~~JavaScript
function a() {
  //関数スコープ
}

{
 //ブロックスコープjavascriptでは{}の中と言う意味
 変数の宣言で使えるのは
    let , const

}
~~~

###レキシカルスコープ
レキシカルとはプログラミングではどこになにがかかれているかという意味
実行中のコードから見た外部スコープのこと

レキシカルスコープとはコードを書く場所によって参照できる変数が変わるスコープのこと
コードを記述した時点で決定するため「静的スコープ」とも言う

~~~JavaScript
let a = 2;

function fn1(){
  let b = 1;
  function fn2(){
    let c = 3;
  }
  fn2();
}
fn1();
~~~

###スコープチェーン
スコープが複数階層で、連なっている状態

~~~JavaScript
//スコープが複数階層になっている場合一番内側の変数から探しにいく

let a = 2;

function fn1(){
  let a = 1;
  function fn2(){
    let a = 3;
    console.log(a);
  }
  fn2();
}
fn1();

>>3
~~~

###クロージャー
レキシカルスコープの変数を関数が使用している状態

~~~JavaScript

function incrementFactory(){

    let num = 0;

    function increment(){
        num = num + 1;
        console.log(num);
    }

    return increment;
}

const increment = incrementFactory;

increment();
increment();
increment();
increment();

~~~

###クロージャー（動的）

~~~JavaScript

function addNumberFactory(num){
    function addNumber(value){
      return num + value;
    }
    return addNumber;
}

const add5 = addNumberFactory(5);
const add10 = addNumberFactory(10);
const result = add10(10);
console.log(result);

>>20
~~~

###即時関数(IIFE)
関数定義と同時に一度だけ実行される関数
実行結果が呼び出し元に返却される

~~~JavaScript
function a() {
  console.log('called');
}

a();

let c = (function(){
  console.log('called');
  return 0;
})

console.log(c);

let b = function(){
  console.log('called');
}();

~~~

##デフォルト値
初期値を入れないとundefinedが出力される

~~~JavaScript
const sayHello = (name) => console.log(`こんにちは${name}さん`);
sayHello();
>>こんにちはundefinedさん

const sayHello = (name="初期値") => console.log(`こんにちは${name}さん`);
sayHello();
>>こんにちは初期値さん 

~~~


##変数
###厳格な等価性と抽象的な等価性

~~~JavaScript
//厳格な等価性(型の比較あり)
a === b

//抽象的な等価性（型の比較なし）
a == b

~~~

###falsyとtruthy
falsyな値とはBooleanで真偽値に変換した場合falseになる値の事

~~~
falsyな値
・false
・null
・0
・0n
・undefined
・NaN
・""

truthyな値
・上記以外
~~~

##分割代入


~~~JavaScript
//オブジェクト
const myprofile = {
  name: "cherry",
  age: 16
};

const massege = `名前${myprofile.name}で${myprofile.age}歳です`;
console.log(massege);

//分割代入

const { name, age} = myprofile;
const massege2 = `分割代入の名前${name}で${age}歳です`;
console.log(massege2);

//配列の場合

const myprofile = ['cherry', 16];

const massege3 = `配列名前${myprofile[0]}で${myprofile[1]}歳です`;
console.log(massege3);
//分割代入（配列の場合）
const [name, age] = myprofile;
const massege4 = `分割代入の名前${name}で${age}歳です`;

console.log(massege4);

~~~

##AND条件OR条件

~~~JavaScript
//記述方法
a && b
a || b

//値の初期化を簡略化できる
function hello(name){
  name = name || 'Tom';
  console.log('Hello' + name);
}

hello('Bob')

let name;

name && hello(name);
~~~

##関数とオブジェクト

###プリミティブ型とオブジェクト

・データ型ではプリミティブ型とオブジェクトが存在する
・オブジェクトは参照を名前付きでしている入れ物

・プリミティブ型は値の比較
・オブジェクトは参照の比較

【プリミティブ型】
String, Null, Number, Symbol, Boolean, Biglnt, Undefined

【オブジェクト】
Object

###関数
関数は「実行可能」なオブジェクトである

prop「属性」

~~~JavaScript

function a(){
  console.log('hello');
}

a.prop = 0;
a.method = function(){
  console.log('method');
}

a();
a.method();
console.log(a.prop);

>>hello
>>method
>>0
~~~

###コールバック関数
他の関数に引数として渡される関数

~~~JavaScript
//関数はオブジェクトとして扱える、関数を引数として渡せる

function hello(){
  console.log('hello');
}

function fn(cb){
  cd();
}

fn(hello);

>>hello

~~~

##this
呼び出し元のオブジェクトへ参照を保持するキーワード

オブジェクトのメソッドとして実行された場合
'this'→呼び出し元オブジェクト

関数として実行された場合
'this'→グローバルオブジェクト

~~~JavaScript

const person = {
  name: 'Tom',
  hello: function(){
    console.log('Hello' + this.name)
  }
}
person.hello();

>>Hello
>>Tom
~~~

###bindと'this'
bindによって'this'や引数を固定した新しい関数を作成
→bindによるthisの束縛

~~~JavaScript
function a(name){
    console.log('hello' + name);
}

const b = a.bind(null, 'Tim')
b();

~~~


###call,applyと'this'
bind→'this'や引数の参照先を変更、使用時点で実行しない
call,apply→'this'や引数の参照先を変更、同時に関数を実行する


~~~JavaScript
function a(name, name1){
    console.log('hello' + name + ' ' + name1)
}

const tim = {name: 'Tim'};

const b = a.bind(tim);

b();

//配列の場合には
a.apply('tim', ['Tim', 'Bob']);
//変数が独立している場合には
a.call(tim, 'Tim', 'Bob');
~~~

###アロー関数
無名関数を記述しやすくした省略記法
アロー関数はthis,argments,new,prototypeの値を保持できない

~~~JavaScript

//従来の関数
 function func1(str){
   return str;
}

//関数を変数にいれて使うこともできる
const func1 = function(str){
  return str;
} 
console.log(func1("func１です"));
>>func１です 

//関数を変数にいれて使うこともできる
const func1 = function(str){
  return str;
} 
console.log(func1("func１です"));
>>func１です 

//アロー関数
const func2 = (str) => {
  return str;
}
console.log(func2("func2です"))

//もしくは
const func2 = (str) => str;


~~~


~~~JavaScript
const b = name => 'hello ' + name;
console.log(b('Tom'))

>>hello Tom
~~~

##コンストラクター関数
新しくオブジェクトを生成するための雛形となる関数

newでオブジェクトを生成することを「インスタンス化」
newで生成したオブジェクトを「インスタンス」

~~~JavaScript

function Person(name, age){
    this.name = name;
    this.age = age;
}

const bob = new Person('Bob', 18)
const tom = new Person('Tom', 65)
const sun = new Person('sun', 34)

~~~

##prototype
・オブジェクトに存在する特別なプロパティ
・コンストラクター関数と合わせて使用

~~~JavaScript

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.hello = function(){
    console.log('hello' + this.name)
}

const bob = new Person('Bob', 18)
const tom = new Person('Tom', 65)
const sun = new Person('sun', 34)

bob.hello();
tom.hello();

~~~

###new演算子
コンストラクター関数からインスタンスを作成するために使用する演算子


~~~JavaScript
//コンストラクター関数の戻り値がオブジェクト
function F(a, b){
    this.a = a;
    this.b = b;
    return {};
}

F.prototype.c = function() {}
//残余引数構文で、不定数の引数を配列として表す
function newOpe(c, ...args){
    console.log(args);
}

const insta = newOpe(F ,1 ,2);
console.log(insta);

>>(2) [1, 2]

//コンストラクター関数の戻り値がオブジェクト以外
function F(a, b){
    this.a = a;
    this.b = b;
}

F.prototype.c = function() {}

function newOpe(c, ...args){
    const _this = Object.create(c.prototype);
    const result = c.apply(_this, args);
    console.log(result, _this);

    return _this;
}

const insta = newOpe(F ,1 ,2);
console.log(insta);

>>undefined F {a: 1, b: 2}
~~~

###instanceof
どのコンストラクターから生成されたオブジェクトかを確認する

~~~JavaScript

//Fがコンストラクターとして定義

function F(a, b){
    this.a = a;
    this.b = b;
    // return {a: 1};
}

F.prototype.c = function(){}

const instance = new F(1, 2);
console.log(instance instanceof F)

>>true

~~~

###クラス
コンストラクター関数をクラス記述でかけるようにしたもの

~~~JavaScript
class Person {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    hello(){
        console.log('hello' + this.name)
    }
}

const bob = new Person('Bob', 23);
console.log(bob);


>>Person {name: "Bob", age: 23}
~~~

##クラス継承
他のクラスのプロパティーとメソッドを継承すること

~~~JavaScript
class Person {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    hello(){
        console.log('hello' + this.name)
    }
}

class Japanese extends Person {
    constructor(name, age, gender){
        super(name, age);
        this.gender = gender;
    }
    hello(){
        console.log('konnitiwa' + this.name);
    }
    bye(){
        console.log('sayonara' + this.name);
    }
}

const bob = new Japanese('Bob', 23, 'men');
console.log(bob);


>>Japanese {name: "Bob", age: 23, gender: "men"}
~~~

###スーパー
継承元の関数を呼び出すためのキーワード

##反復処理
###ループ文
~~~JavaScript
for(let i = 0; i < 10; i++){
    console.log(i);
}

let i = 0;
while(i < 10){
    console.log(i);
    i++;
}
~~~
###演算子と優先順位
演算子とは・・・値（オペランド）を元に処理を行い、結果を返す記号のこと

演算子の優先順位
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

~~~JavaScript
let a = 1 + 2 * 3;
console.log(a);

>>7

let b = (1 + 2)* 3;
console.log(b);

>>9

~~~

##ループ文とブロックスコープ
ループを使ったブロックスコープの場合には、宣言したループごとに全く異なるメモリー空間に参照を保持する

~~~JavaScript
for(let i =0; i < 5; i++){
  var j = i * 2;
  setTimeout(function(){
    console.log(j);
  }, 1000);
  
}
>>⑤ 8

~~~

##配列とループ文

~~~JavaScript
const array = [1, 2, 3, 4, 5];

for(let i =0; i < array.length; i ++){
  console.log(array[i]);
}

let v, i = 0;
while(v = array[i++]){
  console.log(v);
}

~~~

##for...inと列挙可能性
「for...in」・・・列挙可能プロティーに対して順不同で反復処理を実行する
プロトタイプチェーン内も列挙対象となる→Object.hasOwnProperty()
Symbolで定義したプロパティは「for...in」で列挙対象にならない

~~~JavaScript
const obj = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: 'value3'
}

Object.prototype.method = function(){}
//enumerable: falseにすると列挙対象から外れる
Object.defineProperty(Object.prototype, 'method',{
  enumerable: false
});

for(let key in obj){
  console.log(key, obj[key]);
}


//Symbolで定義した場合
const s = Symbol();
const obj = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: 'value3',
  [s]: 'value4'
}

Object.prototype.method = function(){}
//enumerable: falseにすると列挙対象から外れる
Object.defineProperty(Object.prototype, 'method',{
  enumerable: false
});

for(let key in obj){
  console.log(key, obj[key]);
}

~~~

##for...ofと反復可能性
イテレーターを持つオブジェクトの反復操作を行う
「イテレーター」とは反復操作を行う際に使用するオブジェクト

オブジェクトに格納されているイテレーターの挙動に依存する

~~~JavaScript
const array = ['a', 'b', 'c'];

for(let v of array){
  console.log(v)
}

~~~

###MapとSet

「MapとSet」・・・データを管理するための入れ物
コレクションとも呼ぶ

~~~JavaScript
//Map
const map = new Map();
const key1 = {};

map.set(key1, 'value1');
console.log(map.get(key1))

const key2 = function(){}
map.set(key2, 'value2')
console.log(map.get(key2))

let key3;
map.set(key3 =0, 'value3')
console.log(map.get(key3))

map.delete(key3);
console.log(map.get(0))

for(const[k,v] of map){
  console.log(k)
}

//Set
const s = new Set();
s.add(key1);
s.add(key2);
s.add(key3);
s.delete(key3);

console.log(s.has(key2))

for(let k of s){
  console.log(k)
}
~~~

##非同期処理
javaScriptはメインスレッドの上で実行されている
###同期処理と非同期処理
【同期処理】
・同期処理ではメインスレッドでコードが順番に実行される
・同期処理では一人の処理が完了するまで次の処理には進まない

【非同期処理】
・非同期処理は一時的にメインスレッドから処理が切り離される


###タスクキュー
実行待ちの非同期処理の行列
キューの仕組みを「先入れ先出し」という。FIFO(First In, First Out)
タスクキューに入った処理（タスク）が非同期で実行される




##参考
【JS】初級者から中級者になるためのJavaScriptメカニズム
【JavaScript＆CSS】ガチで学びたい人のためのWEB開発徹底実践（フロントエンド編）