Simulating a with statement to demonstrate the dangers.
Created
December 22, 2016 16:37
-
-
Save HeilTec/ff62f1b75d6ced599ad33c795cf63331 to your computer and use it in GitHub Desktop.
Demonstration of why not to use the with statement.
This file contains 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
/** | |
* how_with_works.js 2016.12.22 HeilTec | |
* | |
* To demonstrate how the 'with' statement works and why it can hide mistakes | |
* this code outlines some of the possible outcomes of this construction: | |
* -------------------------- | |
* | with (unknownObject) { | | |
* | result = value | | |
* | } | | |
* -------------------------- | |
* In a nodejs process the global object is named 'global' and in a browser it is called 'window' | |
* | |
* to test the 4 outcomes that doesn't fail uncomment any one of the following: | |
*/ | |
// unknownObject = { other:0 }; value = 111; | |
// unknownObject = { result: undefined }; value = 222; | |
// unknownObject = { value: 333 }; | |
// unknownObject = { result: undefined, value: 444 }; | |
/** | |
* Provoke bad errors by uncommenting one of these. | |
*/ | |
// var unknownObject; | |
// var unknownObject=1; | |
simulate = 1; | |
if (simulate) { | |
try { | |
if (!unknownObject) { // falsy fails if not defined | |
console.error('The unknownObject was null or undefined'); | |
} else { | |
if (Object.keys(unknownObject).indexOf('value') === -1) { | |
if (Object.keys(unknownObject).indexOf('result') === -1) { | |
try { | |
result = value; // global.result = global.value | |
} catch(e){ | |
console.error('The value was never allocated', e.message); | |
} | |
} else { | |
unknownObject.result = value; // global.value | |
} | |
} else { | |
if (Object.keys(unknownObject).indexOf('result') === -1) { | |
result = unknownObject.value; // global.result | |
} else { | |
unknownObject.result = unknownObject.value; // Both in the object | |
} | |
} | |
} | |
} | |
catch(e) { | |
console.error('The unknownObject was never allocated\r\n', e.message); | |
} | |
} else { | |
try { | |
with (unknownObject) { // [jshint] Don't use 'with'. (W085) | |
result = value; | |
} | |
} catch(e) { | |
console.log('Runtime: ', e.message); | |
} | |
} | |
/** | |
* Some mistakes are caught by runtime. | |
* Reference errors will occur when the object is not defined | |
* or the global.value is used and not defined. | |
* | |
* Notice that it is only through try/catch that 'undefined' can be differentiated from not defined. | |
*/ | |
try { | |
console.log('unknownObject.result: ', unknownObject.result); | |
} catch(e) { | |
console.log('Result: ', e.message); | |
} | |
try { | |
console.log('global.result: ', result); | |
} catch(e) { | |
console.log('Result: ', e.message); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment