What is "with" for in Javascript?

Asked

Viewed 1,056 times

63

What is the purpose of the with in Javascript?

It works only to get the object values as if it were a variable, or it is also possible to set or change properties through it?

Example:

var obj = {nome: 'Stack Overflow'}

with (obj) {
  console.log(nome); //Imprime: 'Stack Overflow'
}

3 answers

55


It is only to facilitate typing when you will access multiple members of an object.

As your example shows you can type only nome and didn’t need to type obj.nome to access the member.

The gain is very small and it can bring ambiguity problems so its use is not recommended. Consider it as something not existing in the language. Of course you can use in some case where it becomes clear there is no ambiguity and you will access many members of an object of a very long name, but still the gain is very small.

Ambiguity can occur because you no longer know if you are accessing a local variable (including parameter), global, an existing property in the prototype, or if you are referring to a member of the object. Example using your object:

function f(nome, obj) {
    with (obj) {
        console.log(nome);
    }
}

And now, which nome it will use, the parameter or the member of obj? Note that it gets worse if you have a global flame variable nome - although it should not have global variables.

If you have a very large object name and think that in addition to typing a lot (if you don’t have an IDE that helps) or the text gets too large you can solve this by making the name very short. And it’s called saving typing the o. is important, there should rethink its coding criteria:

var o = objeto_de_nome_muito_grande_mas_que_nao_deveria_ter_sido_nomeado_assim;
console.log(o.nome);

Using the with:

with({o:objeto_de_nome_muito_grande_mas_que_nao_deveria_ter_sido_nomeado_assim}){
    console.log(o.nome);
};

The examples are for demonstration only. Of course this is only worth doing if you will use the object several times.

As always, if you have a good reason in a specific situation and you are fully aware that there will be no problems there, you can even use it. In fact, there are those who demonstrate good utility of with. This may be a legitimate form of use:

with({f:open("x.txt")}){
    var data = f.read(1);
}

I put in the Github for future reference.

In Strict mode cannot use this syntax.

Documentation on the MDN.

  • 1

    Very good! Actionscript also has, now I see why many programmers do not use it!

  • 3

    @bigown, I see a utility in the case of a template engine. Because, instead of accessing the scope through the object passed by parameter, we can use with to access as if the properties were the variable. Classic example is underscore.js. has an excerpt similar to this: with(obj || {}) {}

  • 1

    The reply of the friend Marco Paulo Ollivier (below) is also very pertinent because it addresses scopos, which is something that sometimes confuses in javascript by the fact that simple blocks do not create scopo.

  • The use that bigdown called legitimate is a variable statement at the block level. Perhaps he could make that clearer in the answer.

  • Just as a curiosity, "with" is very old, appeared in Wirth’s original Pascal language.

  • Interestingly, I didn’t even know this existed in the Javascript language, I never had to use something like this in my applications, I believe I didn’t know "with" anymore for this reason, and from what I understand, it is easily replaceable by the normalized construction.

  • 1
Show 2 more comments

13

Javascript, with is a resource of the language able to circumvent the lexical scope, that is, independent of the order of arrangement of the variables, with will take a past expression as a reference as its scope. It is the native way of extending the scope of an instruction, functioning as a shortcut to recurring accesses to an expression.

function foo(x, respostas) {
with (respostas) {
       x = 2; // Estamos atribuindo um novo valor à variável x dentro de o
}

if( (x + x) === respostas.x) { // 1 + 1 = 2 ?
       console.log('Sabemos somar');
}

console.log('Confira a resposta: ' + (x + x)); // Ooops ... retorna 4; isso pode não ser esperado
}

var o = {
       y : 2
};

f(1,o);

If the object passed by reference to the with does not have one of the manipulated attributes, the compiler will raise its declaration to the nearest scope in the hierarchy, in our case the scope of foo. No warning will be released and the variable will be changed to the nearest scope. If it has an identifier with the same denomination, the Compiler will perform an assignment (LHS: lefthand-side) and our value in the context of foo will be lost.

Source: https://javaniaco.wordpress.com/2015/01/28/blocos-como-escopo-a-declaracao-with/

3

Javascript is controversial. A few years ago, mozila showed how deprecated in the documentation, around 2010. Later it was removed from this condition placed only a warning to avoid use. It is still uncertain whether it will actually be removed or not.
Currently the notice in the documentation is quite explitic on the importance of NOT using. Therefore it is important to follow the recommendation.

I have never particularly used it in the way in the examples of the other answers. I have always used it only to help access the properties of an object. As an example, "simulate" the namespace as in PHP.

It is obvious that it goes far from namespace functionality in PHP.

Example:

<script>

Foo = {
    Sample1: function (param1, param2) {
        return param1 + ' statement is ' + param2 + '.';
    },
    Sample2: function () {
        return 'don\'t cry, baby';
    }
};

with(Foo) {
    document.write(Sample1('with', 'deprecated') + ' ' + Sample2());
}
</script>

The code is cleaner.

If it had functions with equal names, under different contexts, just create a "namespace" for both and was solved in an "elegant".

It’s a cool feature that helps organize code by avoiding conflicts between scripts from different libraries. *When they are organized within the scope of an object..

It still works and will work for a few more years. Maybe until 2025 or a little later (I invented the year here on time, blz?). But we must follow the recommendation of the documentation. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with

I just posted this because I didn’t see it in any of the other highly positive responses, to talk about the recommendation on NOT USING the statement with.

Note: The above example is didactic with illustrative purpose. Because the focus here is not on how to simulate namespace.

  • 1

    I think it would be unfair for the question to continue with -1 since you edited it. + 1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.