Re: [問題] 關於setTimeout寫法

看板Ajax作者 (人類)時間6年前 (2018/09/16 00:42), 編輯推噓10(1004)
留言14則, 12人參與, 6年前最新討論串2/2 (看更多)
setTimeout 接受兩種參數︰ var timeoutID = scope.setTimeout(function[, delay, param1, param2, ...]); var timeoutID = scope.setTimeout(code[, delay]); 你的正常寫法和錯誤寫法,分別對應第一種、第二種呼叫方法,這裡就不說明。 來看你的錯誤寫法︰ : setTimeout(console.log(2),1000); console.log(2) 會呼叫 console.log 這個函式,並傳入參數 2。console.log 這個函式 沒有回傳值,得到的結果是 undefined。也就是說,你的錯誤寫法相當於 1. 執行 console.log(2) 之後 2. 使用 undefined 作為第一個參數傳入 setTimeout︰ setTimeout(undefined,1000); 那為什麼沒有錯誤? 因為當 setTimeout 接受到的第一個參數不是函式的時候,會嘗試將該數值轉成字串。也 就是說,它相當於︰ setTimeout((undefined).toString(),1000); setTimeout('undefined',1000); 你相當於在一秒後執行了一段內容為「undefined」的程式碼。 基於這個特性,我們其至可以把要執行的程式碼設置成 toString 的回傳內容︰ const foo = {}; foo.toString = () => "console.log('hello')"; setTimeout(foo, 1000); // 在一秒後印出 hello 參考︰ * MDN 上的 setTimeout 文件︰ https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout (縮︰https://is.gd/YOpwh2) * setTimeout 的詳細實作參考︰ https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout (縮︰https://is.gd/4DlMT2) -- 額外補充,如果你希望在遇到這種情況時能產生錯誤提醒開發者,可以使用具有 type check 功能的工具,例入 TypeScript 或 Flow。 以下是在 Flow 的 REPL,可以看到對 setTimeout 傳入 undefined 產生的錯誤︰ https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBnApgFwCoCWAtlnAK44AUAxnAHYZwxYB08A5pQEwCUANGACMABlE8A3KiA (縮︰https://is.gd/O5Bjdk) -- ▆▄   -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.250.158.95 ※ 文章網址: https://www.ptt.cc/bbs/Ajax/M.1537029763.A.19D.html

09/16 13:05, 6年前 , 1F
09/16 13:05, 1F

09/16 13:56, 6年前 , 2F
謝謝大大解釋
09/16 13:56, 2F

09/16 14:18, 6年前 , 3F
09/16 14:18, 3F

09/16 23:59, 6年前 , 4F
這個教學太精闢了!!!!
09/16 23:59, 4F

09/17 11:17, 6年前 , 5F
大推(Y)
09/17 11:17, 5F

09/17 11:49, 6年前 , 6F
推~
09/17 11:49, 6F

09/28 15:06, 6年前 , 7F
簡潔明瞭,讚
09/28 15:06, 7F

09/29 09:48, 6年前 , 8F
清楚明瞭
09/29 09:48, 8F

09/30 01:15, 6年前 , 9F
解釋得太棒了!
09/30 01:15, 9F

10/10 01:35, 6年前 , 10F
推 解釋的很清楚
10/10 01:35, 10F

10/11 11:16, 6年前 , 11F
第二種呼叫方法本身是用 eval 在跑嗎 ?
10/11 11:16, 11F

10/14 01:34, 6年前 , 12F
這個還滿有趣的XD 剛試了一下
10/14 01:34, 12F

10/14 01:34, 6年前 , 13F
setTimeout({toString:function(){return 'console.log(\'abc
10/14 01:34, 13F

10/14 01:35, 6年前 , 14F
\')';}},2000); 是會跑的
10/14 01:35, 14F
文章代碼(AID): #1RdJQ36T (Ajax)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1RdJQ36T (Ajax)