Last active
June 20, 2021 22:12
-
-
Save mfdj/08938f77dd6f6c578e7e78d4af2a5af9 to your computer and use it in GitHub Desktop.
In ES5 undefined is protected at the global level but it's not quite bulletproof
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head><meta charset="UTF-8"></head> | |
<!-- Normal script --> | |
<script> | |
// starting in ES5 window.undefined is read-only | |
undefined = 'NOT UNDEFINED' | |
console.log(undefined === window.undefined) // prove that we are scoped to window object (global object in node) | |
console.log(undefined !== 'NOT UNDEFINED') | |
console.log(undefined === void 0) // the symbol window.undefined will always map to the undefined value-literal (the void operator allows consistent access to the undefined value-literal) | |
;(function() { | |
var undefined = 'CAN SHADOW' // variable shadowing allows us to redfine the undefined symbol locally | |
console.log(undefined === 'CAN SHADOW') | |
;(function() { | |
console.log(undefined === 'CAN SHADOW') // effects all nested contexts | |
console.log(window.undefined === void 0) // but recall that the explicit global scope is available to us | |
})() | |
})() | |
;(function() { | |
let undefined = 'SHADOWING WORKS WITH LET' | |
console.log(undefined === 'SHADOWING WORKS WITH LET') | |
;(function() { | |
console.log(undefined === 'SHADOWING WORKS WITH LET') | |
})() | |
})() | |
;(function() { | |
const undefined = 'SHADOWING WORKS WITH CONST' | |
console.log(undefined === 'SHADOWING WORKS WITH CONST') | |
;(function() { | |
console.log(undefined === 'SHADOWING WORKS WITH CONST') | |
})() | |
})() | |
;(function() { | |
var undefined = 'STILL SHADOWING' | |
window.undefined = 'SILENTLY FAILS' | |
console.log(window.undefined !== undefined) | |
})() | |
;(function() { | |
'use strict' | |
var undefined = 'STILL SHADOWING EVEN IN STRICT MODE' | |
console.log(window.undefined !== undefined) | |
})() | |
;(function() { | |
'use strict' | |
try { | |
window.undefined = 'THIS WILL THROW TypeError' | |
} catch (e) { | |
console.warn(e) | |
} | |
})() | |
</script> | |
<!-- Module script https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type --> | |
<script type="module"> | |
// In a module "use strict" is implict, so attempting to write to window.undefined throws | |
try { | |
window.undefined = 'THIS WILL THROW TypeError' | |
} catch (e) { | |
console.warn(e) | |
} | |
;(function() { | |
const undefined = 'CAN SHADOW' // variable shadowing allows us to redfine the undefined symbol locally | |
console.log(undefined === 'CAN SHADOW') | |
;(function() { | |
console.log(undefined === 'CAN SHADOW') // effects all nested contexts | |
console.log(window.undefined === void 0) // but recall that the explicit global scope is available to us | |
})() | |
})() | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment