Skip to content

Instantly share code, notes, and snippets.

@HeilTec
Created December 22, 2016 16:37
Show Gist options
  • Save HeilTec/ff62f1b75d6ced599ad33c795cf63331 to your computer and use it in GitHub Desktop.
Save HeilTec/ff62f1b75d6ced599ad33c795cf63331 to your computer and use it in GitHub Desktop.
Demonstration of why not to use the with statement.
/**
* 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