I know with
is supposedly a "Bad Part" but I never cared, because I just used it carefully (ditto, btw, with var
statements in blocks). Now, I understand that with
has been banished from EcmaScript 5.0 strict mode.
Here's my use-case: I have a library that exports some 20 or 30 functions. Most of my code never uses any of the library but the parts that do, use them a lot.
Right now, my code looks like:
with (mylib) {
f1(f2(f1(), f3())); // five or 10 more lines like this
}
To be compliant, I will have to...
a) Move all of the functions to global scope (yuck).
b) mylib.f1(mylib.f2(mylib.f1(), mylib.f3()));
(which is verbose)
c) var x = mylib; x.f1(x.f2(x.f1(), x.f3()));
(which is slightly less verbose but less meaningful).
Please tell me that there's some better solution out there now. What I want is some way to export the contents of a object into a level of scope (which is exactly what with
was for).
EDIT:
Something I should have made clearer. I don't want people to explain to me why I don't want to do what I do want to do; I want people to explain to me how to do what I do in fact want to do.
The thing is, for reasons beyond my control, the exports of the library all have very recognizable names. Instead of calling them f1, f2, and so on, let's say they're called Bobs_Library_Function_F1, Bobs_Library_Function_F2, and so on.
I just don't want a lot of code that looks like
Bobs_Library.Bobs_Library_Function_F1(Bobs_Library.Bobs_Library_Function_F2(Bobs_Library.Bobs_Library_Function_F1(), Bobs_Library.Bobs_Library_Function_F3()));
(The real names aren't that bad, they're quite beautiful actually, and prefixing cuts into that.)
Anybody who seriously disagrees here, well, I hope you never use $.whatever
when you are supposed to be using jQuery.whatever
because that would make you look like a big ole hypocrite.
I'm thinking of using $$.f1
...
FURTHER EDIT
Seriously, thanks for all the input, but I'm not looking for a poll on whether (a), (b), or (c) is the best. I'm looking for choice (d) that does what with
does so well.
Do I at least get block-scoping out of strict mode?
with
is bad, because inside the block, you have no idea where the variables are coming from. Is f1
equal to mylib.f1
or window.f1
?
I would suggest going with option b)
. You can use c)
if you want, it may help with long object names, but b)
is the way to go.
EDIT: Another suggestion is to use option a)
, but then remove the references from window when you're done. Also, be careful not to overwrite any existing properties in window
. You can throw them into another object for save keeping, if you want. Building upon @Alex's answer:
var bkupWin = {}; // Object to store existing window properties
for(var key in myLib) {
if(myLib.hasOwnProperty(key)){
if(window.hasOwnProperty(key)){
bkupWin[key] = window[key]; // Backup current property
}
window[key] = myLib[key]; // Add property to window
}
}
f1(f2(f1(), f3()));
for(var key in myLib){
if(myLib.hasOwnProperty(key)){
delete window[key]; // Remove property from window
if(bkupWin.hasOwnProperty(key)){
window[key] = bkupWin[key]; // Restore old property
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With