第一引数の関数を第二引数に渡したミリ秒後に実行するsetTimeout
メソッド。
下記のように関数に引数を取ると即実行されて意図どおりになりません。
function sayHello(name = 'Tom'){
console.log(`hello ${name}`)
}
setTimeout(sayHello('John'), 3000) // 間髪入れず「hello John」が出力
setTimeoutに渡さなければならないのは関数オブジェクトであり、関数の実行結果ではないからです。
そのため、引数を取らない場合でも即実行されてしまいます。
setTimeout(sayHello(), 3000) // 間髪入れず「hello Tom」が出力
setTimeout(sayHello, 3000) // これならOK。正しい渡し方
どうすれば、引数を渡しつつ指定ミリ秒後に関数を実行できるのか。
無名関数をわたす
実行したい関数を包含した無名関数をsetTimeoutの引数とすることで、nameを指定することが可能です。
function sayHello(name = 'Tom'){
console.log(`hello ${name}`)
}
setTimeout(function(){
sayHello('John')
}, 3000)
bindメソッドを使う
function sayHello(name = 'Tom'){
console.log(`hello ${name}`)
}
setTimeout(sayHello.bind(null, 'John'), 3000)
bind()は、下記の性質を持つ新たな関数オブジェクトを作成するメソッドです。
- 第一引数にとるオブジェクトを呼び出し元の関数内でthisとして参照する
- 第二引数にとる値を呼び出し元の関数内で引数として参照する
今回はthisを使用しないため、第二引数のみ指定しています。
趣旨から少し外れますが、第一引数にオブジェクトをわたすことで下記のような書き方も可能です。
const obj = {
name: 'John'
}
function sayHello(name = 'Tom'){
console.log(`hello ${this.name}`)
}
setTimeout(sayHello.bind(obj), 3000) // 3秒後に「hello John」が出力
setTimeoutの第三引数以降に指定する
コメントにて言及いただきました。
setTimeoutの第三引数以降に渡す値は、実行する関数の引数として参照されます。
function sayHello(name1, name2){
console.log(`hello ${name1} and ${name2}`)
}
setTimeout(sayHello, 3000, 'John', 'Tom') // 3秒後に「hello John and Tom」が出力