Skip to content

Commit 156d265

Browse files
feat: A setTimeout object (#210)
* setTimeout(not-a-function, ) * Fix typo & add to list * fix: fix formatting issues in the PR Co-authored-by: Denys Dovhan <denysdovhan@gmail.com>
1 parent d58f43f commit 156d265

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Currently, there are these translations of **wtfjs**:
115115
- [`arguments` binding](#arguments-binding)
116116
- [An `alert` from hell](#an-alert-from-hell)
117117
- [An infinite timeout](#an-infinite-timeout)
118+
- [A setTimeout object](#a-settimeout-object)
118119
- [Double dot](#double-dot)
119120
- [Extra Newness](#extra-newness)
120121
- [Why you should use semicolons](#why-you-should-use-semicolons)
@@ -1999,6 +2000,49 @@ Timeout duration was set to 1.
19992000
- [Node.js Documentation on Timers](https://nodejs.org/api/timers.html#timers_settimeout_callback_delay_args)
20002001
- [Timers](https://www.w3.org/TR/2011/WD-html5-20110525/timers.html) on W3C
20012002

2003+
## A `setTimeout` object
2004+
2005+
Guess what would happen if we set an callback that's not a function to `setTimeout`?
2006+
2007+
```js
2008+
setTimeout(123, 100); // -> <timeoutId>
2009+
// > 'called'
2010+
```
2011+
2012+
This is fine.
2013+
2014+
```js
2015+
setTimeout('{a: 1}', 100); // -> <timeoutId>
2016+
// > 'called'
2017+
```
2018+
2019+
This is also fine.
2020+
2021+
```js
2022+
setTimeout({a: 1}, 100); // -> <timeoutId>
2023+
// > 'Uncaught SyntaxError: Unexpected identifier setTimeout (async) (anonymous) @ VM__:1'
2024+
```
2025+
2026+
This throws an **SyntaxError**.
2027+
2028+
Note that this can easily happen if your function returns an object and you call it here instead of passing it! What if the content - policy is set to `self`?
2029+
2030+
```js
2031+
setTimeout(123, 100); // -> <timeoutId>
2032+
// > console.error("[Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'report-sample' 'self' ")
2033+
```
2034+
2035+
The console refuses to run it at all!
2036+
2037+
### 💡 Explanation:
2038+
2039+
`WindowOrWorkerGlobalScope.setTimeout()` can be called with `code` as first argument, which will be passed on to `eval`, which is bad. Eval will coerce her input to String, and evaluate what is produced, so Objects becomes `'[object Object]'` which has hmmm ... an `'Unexpected identifier'`!
2040+
2041+
- [eval()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) on MDN (don't use this)
2042+
- [WindowOrWorkerGlobalScope.setTimeout()](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) on MDN
2043+
- [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
2044+
- [Timers](https://www.w3.org/TR/2011/WD-html5-20110525/timers.html) on W3C
2045+
20022046
## Double dot
20032047

20042048
Let's try to coerce a number to a string:

0 commit comments

Comments
 (0)