I am learning JS now and can not understand why 'use strict' directive does not work for a callback for setTimeout? As I know for use strict it should be undefined but always have global object.
function f() { 'use strict' console.log(this === window) } function g() { console.log(this === window) } setTimeout(g,1000) // expect true, have true setTimeout(f,1000) // expect false, have true
When setTimout()
invokes a function in the browser, it sets the this
to window
. That is why it is not affected by strict mode - the this
value is provided, instead of being left unset.
The specification for setTimeout
can be found in the HTML standard
The timer initialization steps , given a
WindowOrWorkerGlobalScope
global , a string orFunction
handler , a number timeout , a list arguments , a boolean repeat , and optionally (and only if repeat is true) a number previousId , are:1. Let thisArg be global if that is a
WorkerGlobalScope
object; otherwise let thisArg be theWindowProxy
that corresponds to global .[...]
9. Let task be a task that runs the following substeps:
If id does not exist in global 's map of active timers, then abort these steps.
If handler is a
Function
, then invoke handler given arguments with the callback this value set to thisArg . If this throws an exception, catch it, and report the exception.[...]
In essence, the result is similar to calling the function like so:
function f(){ 'use strict' console.log(this) } f.call(window)
You may think about this===Window when you call a function like f() in non-strict mode as a default value for this (passed value is undefined ).
But there is also a way to provide this value explicitly eg
f.call(Window)
In that case this is set explicitly and no default value for non-strict this is needed. Both strict and non-strict functions will show the same Window.
Frankly speaking when you pass a function as a callback you do not know how that callback will be called and you need to check the code of a wrapper function.
setTimeout does something like that pseudofunction:
function setTimeout(callback, delay, param3, param4,...){
// waiting a timer
callback.call(Window, param3, param4, ...)
}
PS If you are interested in I posted couple of years ago about that - https://dev.to/smlka/easyspec-how-does-settimeout-invoke-a-callback-function-in-a-browser-44kh
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.