作者eight0 (人类)
看板Ajax
标题Re: [问题] 关於setTimeout写法
时间Sun Sep 16 00:42:34 2018
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://webptt.com/cn.aspx?n=bbs/Ajax/M.1537029763.A.19D.html
1F:推 Kenqr: 推 09/16 13:05
2F:推 blues520520: 谢谢大大解释 09/16 13:56
3F:推 ochitsuite: 推 09/16 14:18
4F:→ peanut97: 这个教学太精辟了!!!! 09/16 23:59
5F:推 cutekid: 大推(Y) 09/17 11:17
6F:推 kyrc: 推~ 09/17 11:49
7F:推 shvanta: 简洁明了,赞 09/28 15:06
8F:推 akccakcctw: 清楚明了 09/29 09:48
9F:推 pk740111: 解释得太棒了! 09/30 01:15
10F:推 ostkaka: 推 解释的很清楚 10/10 01:35
11F:推 visa9527: 第二种呼叫方法本身是用 eval 在跑吗 ? 10/11 11:16
12F:→ y3k: 这个还满有趣的XD 刚试了一下 10/14 01:34
13F:→ y3k: setTimeout({toString:function(){return 'console.log(\'abc 10/14 01:34
14F:→ y3k: \')';}},2000); 是会跑的 10/14 01:35