Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe use of "with" in JavaScript [duplicate]

Tags:

javascript

Pretty much every resource documenting with that I can find warns against using it, mostly because if a variable is not defined it may have unpredictable effects.

I want to understand it so that I can make effective use of it - after all, it's there for a reason. Even eval has its non-evil uses!

So, with that in mind, let's say I want to delete all child nodes from an element, without using elem.innerHTML = "";

Would the following be safe?

with(elem) while(firstChild) removeChild(firstChild);

Note that at this point I'm not caring for readability, just functionality. Since firstChild is a property of, and removeChild a method of, all element nodes, it should be fine to use with this way, right?

Similarly, let's say I want to set some styles.

with(elem.style) {
    color = "red";
    backgroundColor = "black";
    fontWeight = "bold";
}

Since all of these are properties of the style object (even if not defined in the stylesheet, they are there as empty strings), it's fine to use with like this, right?

Am I missing something, or is the constant warning to not use with similar to the one against PHP's mysql extension: a protection against dumb programmers?

like image 704
Niet the Dark Absol Avatar asked Jun 25 '13 08:06

Niet the Dark Absol


2 Answers

The with keyword in Javascript is a bit of a throwback to when it was competing with VBScript in the late 90s. It's still there, but disabled if you 'use strict'; and considered an error by just about every Javascript validator out there.

There are two major problems with it, both related to the way scope works in Javascript:

var color = "green";
var foo = "bar";

with(elem.style) {
    color = "red";
    foo = "something else";
}

What's color now? What is foo? Not only is this confusing code, but due to how Javascript looks up variables in the with scope it's also very slow code as now every statement has an additional scope to search for each variable used.

This is one of the reasons why modern frameworks like jQuery and Prototype use chaining. They use call and apply on functions to control what this represents, meaning that you make calls to this.something rather than with(this){something}.

So to answer your question: there is one good use of with in Javascript - allowing IE4 and IE5 websites written in the 90s to still work today.

That's it. You shouldn't use it in new code.

like image 63
Keith Avatar answered Sep 29 '22 22:09

Keith


The only safe use of with is not using it at all. There's no task that can't be accomplished without it and modern standards outright disable it in strict mode.

For all purposes it is considered a design mistake that is only preserved for backwards compatibility.

like image 41
Oleg V. Volkov Avatar answered Sep 30 '22 00:09

Oleg V. Volkov