JS(VueやReact)をなんとなく使ってしまっているので、色々学習しています。
この記事は下記コースのアウトプットになります。
【JS】初級者から中級者になるためのJavaScriptメカニズム | Udemy
スコープ
- グローバルスコープ
- スクリプトスコープ
- 関数スコープ
- ブロックスコープ
- モジュールスコープ
グローバルスコープ
windowsオブジェクト = グローバルスコープ
関数スコープ
function scope() {
// ここに囲まれたスコープのこと指します
}
ブロックスコープ
{}
で囲まれた範囲のことを指します。
var
を使った場合は、ブロックスコープは生成されません。
var,let,constの違いは、ブロックスコープと巻き上げ - 30歳からのプログラミング
レキシカルスコープ(外部スコープ)
// 下記の場合、関数 a がレキシカルスコープになります。
function a() {
function b() {
console.log('だだだだだ')
}
}
クロージャー
レキシカルスコープを関数として使用している状態のことをさします。
// 下記のような状態のこと
function soto() {
let aaa = "test"
function uchi() {
console.log(aaa)
}
}
プライベート変数を設定する
外部からアクセスできない変数を定義します。
function incrementFactory() {
// 外部からアクセスできない変数
let num = 0;
function add() {
num += 1;
console.log(num);
}
// 関数addを返している
return add;
}
// 変数に関数の実行を定義する
const increment = incrementFactory();
increment(); // 1
increment(); // 2
// プライベート担っているため、外部からは呼び出せない
console.log(num) // エラー
動的な関数
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);
あとこんな書き方もできます。知らんんかった、、、
function factory(val) {
return {
plus: function(target) {
const newVal = val + target;
console.log(`${val} + ${target} = ${newVal}`);
val = newVal;
},
minus: function(target) {
const newVal = val - target;
console.log(`${val} - ${target} = ${newVal}`);
val = newVal;
},
};
}
const cal = factory(10);
cal.plus(5);
cal.minus(5);
即時関数
関数定義と同時に一度だけ実行される関数のことをさします。
実装は以下のようになります。
最初のカッコは、グループ化をさし、次のカッコは、関数の実行のことをさします。
基本的に function
には名前をつけなければいけないので、()
を外したらエラーになります。
// 通常の関数
function test() {
console.log('called');
}
// 即時関数
(function() {
console.log('called');
})()
// 変数に入れる場合は、
const c = (function() {
let val = 10;
function fn() {
console.log('fn is called');
}
return {
val,
fn
};
})()
// 関数の呼び方
c.fn();
// 変数の呼び出し方
console.log(c.val);
暗黙的な型変換
変数が呼ばれた状況によって、変数の型が自動的に変換されるので、覚えておく。
プリミティブとオブジェクト
プリミティブ
オブジェクト以外の物を全て指します。
具体的には、 String, Null, Symbolなどですね。
イミュータブルで、再代入の場合は、値の参照が切り替わります。
コピー
参照先の値がコピーされます。
元の変数を変更しても、元の変数、代入した変数は独立しているので、値は変わりません。
// address に a という変数を使って、値が読み込まれています。
let a = "Yo"
// "Yo"自体(値)がコピーされます
let b = a
// bの向き先(値)が変わります。
b = "Taka"
再代入
constを使う場合、もちろん再代入ができません。
つまり、constを定義した場合は、変数 a
の向き先を変更できなくなるのです。
const a = "Yo"
a = "Taks"
オブジェクト
ミュータブルで、参照を名前付きで管理している入れ物です。
この時のミュータブルの意味は、"Yo"
の値が変わったとしても、propへの参照
が変わらないことから、ミュータブルと呼ばれます。
let a = {
prop: "Yo";
}
コピー
下記図の通り、オブジェクトへの参照がコピーされることになります。(背景色が異なっているところ)
{ prop }
がみている値が変更されるので、元の変数の値も変更されることになります。
let a = {
prop: "Yo"
};
let b = a;
b.prop = "Taka";
再代入
オブジェクトの再代入はできないが、オブジェクト内のプロパティは再代入できます。
比較
オブジェクトのプロパティを比較する必要があり、オブジェクトの比較をしても、参照を比較することになるので、期待する結果とはなりません。