mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
forbidden to set this
for setTimeout (#2511)
This commit is contained in:
parent
bca5cc5041
commit
42d1024cd9
2 changed files with 64 additions and 0 deletions
10
js/timers.ts
10
js/timers.ts
|
@ -181,6 +181,12 @@ function fireTimers(): void {
|
|||
|
||||
export type Args = unknown[];
|
||||
|
||||
function checkThis(thisArg: unknown): void {
|
||||
if (thisArg !== null && thisArg !== undefined && thisArg !== window) {
|
||||
throw new TypeError("Illegal invocation");
|
||||
}
|
||||
}
|
||||
|
||||
function setTimer(
|
||||
cb: (...args: Args) => void,
|
||||
delay: number,
|
||||
|
@ -226,6 +232,8 @@ export function setTimeout(
|
|||
delay: number,
|
||||
...args: Args
|
||||
): number {
|
||||
// @ts-ignore
|
||||
checkThis(this);
|
||||
return setTimer(cb, delay, args, false);
|
||||
}
|
||||
|
||||
|
@ -235,6 +243,8 @@ export function setInterval(
|
|||
delay: number,
|
||||
...args: Args
|
||||
): number {
|
||||
// @ts-ignore
|
||||
checkThis(this);
|
||||
return setTimer(cb, delay, args, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -177,3 +177,57 @@ test(async function timeoutCallbackThis(): Promise<void> {
|
|||
setTimeout(obj.foo, 1);
|
||||
await promise;
|
||||
});
|
||||
|
||||
test(async function timeoutBindThis(): Promise<void> {
|
||||
function noop(): void {}
|
||||
|
||||
const thisCheckPassed = [null, undefined, window, globalThis];
|
||||
|
||||
const thisCheckFailed = [
|
||||
0,
|
||||
"",
|
||||
true,
|
||||
false,
|
||||
{},
|
||||
[],
|
||||
"foo",
|
||||
(): void => {},
|
||||
Object.prototype
|
||||
];
|
||||
|
||||
thisCheckPassed.forEach(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(thisArg: any): void => {
|
||||
let hasThrown = 0;
|
||||
try {
|
||||
setTimeout.call(thisArg, noop, 1);
|
||||
hasThrown = 1;
|
||||
} catch (err) {
|
||||
if (err instanceof TypeError) {
|
||||
hasThrown = 2;
|
||||
} else {
|
||||
hasThrown = 3;
|
||||
}
|
||||
}
|
||||
assertEquals(hasThrown, 1);
|
||||
}
|
||||
);
|
||||
|
||||
thisCheckFailed.forEach(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(thisArg: any): void => {
|
||||
let hasThrown = 0;
|
||||
try {
|
||||
setTimeout.call(thisArg, noop, 1);
|
||||
hasThrown = 1;
|
||||
} catch (err) {
|
||||
if (err instanceof TypeError) {
|
||||
hasThrown = 2;
|
||||
} else {
|
||||
hasThrown = 3;
|
||||
}
|
||||
}
|
||||
assertEquals(hasThrown, 2);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue