0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

スコープ-JavaScript-クロージャー

Last updated at Posted at 2020-08-25

スコープについて。
では早速

let b = 'Hello'
function sample() {
  console.log(b)
}
sample()//Hello
console.log(b)//Hello
b = 'Bye'
console.log(b)//Bye
sample()//Bye

ブロックの外で変数を宣言した場合はどこからでも参照できるし代入可能になる。

function sample() {
  let a = 'Hello'
  console.log(a)//Hello
}
sample()
console.log(a)//エラー

ブロック内で変数を宣言した場合スコープがブロック内になるので
外からは参照できない。

let c = 'Hello'
console.log(c)//Hello
function sample() {
  c = 'Bye'
  console.log(c)//Bye
}
console.log(c)//Hello
sample()
console.log(c)//Bye

外で宣言した変数は中(ブロック内)で再代入することもできる。
今回の場合、最初に__'Hello'を代入して関数内で'Bye'とした場合
関数が実行されたタイミングで変数__c__には
'Bye'が入る為
関数実行後の変数__c__は
'Bye'__となる。

let d = 3
function sample1() {
  let e = 5
  console.log(d)//3
  function sample2() {
    let f = 10
    console.log(d)//3
    console.log(e)//5
    console.log(f)//10
  }
  console.log(f)//エラー
  sample2()
}
console.log(e)//エラー
sample1()
sample2()//エラー

ネストした場合内側のブロックからは外側のブロックの値を参照できるが
外側から中の値は参照できない。

クロージャー

呼び出す度にインクリメントしたい場合など

function increment() {
  let num = 0
  num++
  console.log(num)
}
increment()//1
increment()//1
increment()//1

これだと毎回初期化されてしまうため欲しい結果が得られない

let num = 0
function increment() {
  num++
  console.log(num)
}
increment()//1
increment()//2
increment()//3
num = 0
increment()//1

欲しい結果は得られるが外部から再代入可能になる


function incrementFactory() {
  let num = 0
  function increment() {
    num++
    console.log(num)
  }
  return increment
}
const increment = incrementFactory()
increment()//1
increment()//2
increment()//3
num = 0
increment()//4
console.log(num)//0

こうすることで外部から変数を触れなくできる
今回の場合だとブロックで__変数num__は外から参照できないので
仮に外で新たに__num__を宣言しても関数内の__num__には影響を与えない。

function greeting(value) {
  function userName(name) {
    return value + name
  }
  return userName
}

const hello = greeting('Hello')//valueに'Hello'とはいった関数になる
const bye = greeting('Bye')//valueに'Bye'とはいった関数になる
const result1 = hello('太郎')//この引数がnameに入る
const result2 = bye('次郎')//この引数がnameに入る
console.log(result1)//Hello太郎
console.log(result2)//Bye次郎


//このように書くことでもできる
const greeting = (value) => {
  const userName = (name) => {
    return value + name
  }
  return userName
}
//同じように実行できる

__return__でuserName関数が返ってくるので
__const hello = greeting('Hello')__とした場合、この__hello()__を実行したときに呼ばれるのは
中にある__userName__になる
このように引数の値を変えることで
一つの関数を異なる関数のように扱うことができる

関数宣言は

function func1() {
  console.log('func1')
}
const func2 = function() {
  console.log('func2')
}
const func3 = () => {
  console.log('func3')
}
func1()//func1
func2()//func2
func3()//func3

でも書ける。
以上です!

間違いがありましたらご指摘いただけると嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?