Javascript スコープについて

スコープとは

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

グローバルスコープ  スクリプトスコープ

windowオブジェクト=グローバルスコープ

一般的にはスクリプトスコープもグローバルスコープと呼ばれる。

var a = 0  //グローバルスコープに入れられる
console.log(window.a) //上に同じ
let,const b = 0; //scriptスコープに入れられる。 

関数スコープ  ブロックスコープ

関数スコープはfunction(){}
ブロックスコープは{}内のことを指す //このときのlet const, varの挙動の違いに注意

//関数スコープ
function a(){
let b =0;
console.log(b);
}
a();
//ブロックスコープ  letやconstのみを使える varは全体に定義してしまうのでよくない
{
let c =1;   
const d = function d(){
console.log('d is called');
}
d();
}

モジュールスコープ

 

レキシカルスコープ

コードを書く場所によって参照できる変数が変わるスコープのこと・違う言語ではダイナミックスコープが仕様になっていることも。
コードを記述した時点で決定するため、「静的スコープ」とも呼ばれる。

実行中のコードから見た外部コードのこと(内からは参照できるけど、外からは参照できないよ。)
レキシカルスコープでは関数を定義した時点でスコープが決まる。

var x = 10; 
function A(){
  console.log(x);  //この時の静的なスコープはx=10
}
function B(){
  var x = 1000;  //ここでもxが定義されている
  A();  //この時のxは10?1000?
}
A();  //10
B(); //-> 10 (1000ではない!)
let num =0;
increment();
console.log(num);
function increment(){
num = num + 2;
}

クロージャー

クロージャは「関数」と「その関数が作られた環境」という 2 つのものが一体となった特殊なオブジェクト
クロージャー内で定義された変数はメモリに残る
function fa(){
let a =1;
function fb(){
console.log(a);
}
return fb;}

/*--
関数fnAの内部に ローカル変数hogeが "ほげ" として定義されている。
この ローカル変数hogeを参照できるのは本来、 関数fnAの実行時のみ
その 関数fnAの実行は グローバル変数myFuncが定義された時のみ。
関数fnAの実行により、 ローカル関数fnBが myFuncに代入されている。
myFunc( 関数fnB)を実行すると、"ほげ" とアラートされた。
--*/

function fnA() {
var hoge = "ほげ";
console.log(hoge);


function fnB() {
alert(hoge);
}
return fnB;
}
var myFunc = fnA();

myFunc();

②動的な関数の生成

//動的な関数の生成

function addNumberFactory(num){
function addNumber(value){
return num + value;
}
return addNumber;
}
const add5 = addNumberFactory(5); //numに5が入った時のaddNumber
const result = add5(10);          //numに5が入った時のaddNumberのvalueに10が入る 
console.log(result);

即時関数

即時関数は定義すると即時に実行される関数
(function(仮引数)){}(実引数)

//即時関数
//関数定義と同時に一度だけ実行される関数
//実行結果がreturn呼び出し元に返却される。
let e = (function(d){
console.log('called'+d);
return 0;
})(10);            //console called10

console.log(e);       // 0
即時関数の中の関数や変数を取り出す
let f = (function(){
console.log('called');
let privateVal = 0;
let publicVal = 10;
function privateFn(){
console.log('privateFn is called');
}
function publicFn(){
console.log('publicFn is called');
}
return{
publicVal,
publicFn
};
})()

f.publicFn();    //とか
function calcFactory(val){
return{
plus:function(target){   //こういう書き方とかもあるぞ
const newVal = val + target;
console.log(val + "+" + target + "=" + newVal);
console.log(`${val} + ${target} = ${newVal}`);
val = newVal;
}
};
}
const calc = calcFactory(10);
calc.plus(5);

投稿者 @rongai