Any person who is even mildly experienced with JavaScript has used Object literals. Object literals are a great way to encapsulate information. This is how they work
let person = {
name: 'Umer',
interests: ['javascript', 'webdev']
}
This is a very neat and useful fundamental feature of JavaScript (and other languages) but it can get messy. You may have chains of object literals, and having to refer to them in code can be a pain.
This is an example from a project that simulates light behaviours
updateLines(obj) {
for(let i = 0; i < obj.vertices.length; i++) {
let dx = obj.vertices[(i + 1)%obj.vertices.length][0] - obj.vertices[i][0];
let dy = obj.vertices[(i + 1)%obj.vertices.length][1] - obj.vertices[i][1];
obj.segments[i].pos.set(obj.vertices[i][0], obj.vertices[i][1]);
obj.segments[i].displacement.set(dx, dy);
obj.segments[i].dir = obj.segments[i].displacement.copy().normalize();
}
}
Note how many times I have had to reference the obj
object. This agony makes way for the JavaScript feature that has very well failed (although this has been replaced with a cleaner concept).
with (expression) statement
According to the MDN docs, the with statement extends the scope chain for a statement. This means that if we used with (obj)
in our previous example, it would have been possible for us to remove the reference to obj
in our statements. This clearly makes our code cleaner and easier to manage.
updateLines(obj) {
with(obj) {
for(let i = 0; i < vertices.length; i++) {
let dx = vertices[(i + 1)%vertices.length][0] - vertices[i][0];
let dy = vertices[(i + 1)%vertices.length][1] - vertices[i][1];
segments[i].pos.set(vertices[i][0], vertices[i][1]);
segments[i].displacement.set(dx, dy);
segments[i].dir = segments[i].displacement.copy().normalize();
}
}
}
The example I have shown is not very extreme, but you can imagine if the obj
was part of an object chain, there would be a much more visible improvement in code coherence.
Do NOT use this feature
We looked at how useful this feature is, but it can cause all sorts of problems. For example it produces uncertainty when we might have a local variable by the name of, say, 'length'. If we used the with statement with an object that owns a property by the same name (length), we have a problem. You can read in more detail about the problems this feature can cause here
It is due to these reasons that this feature is now deprecated and is not recommended for use in any code.
ES6 to the rescue
ES6 introduces a very much cleaner way to achieve similar functionality but without the same troubles. This feature is known as object destructuring, and we use this in modern JavaScript to fetch properties from inside of objects into local or global scopes. This feature has many more use cases, and is much more complex (read here), but we will discuss a simpler example here.
This code snippet is from my Live Interactive Drawing Board application
const { name, email, password } = req.body;
if (!name || !password || !email) {
return res.status(400).json({ msg: "Kindly fill all the required fields" });
}
This is some very basic server side code, in nodejs. We pull out three properties from the req.body
object by using curly braces in our declaration, and equating this to our object. The code then checks to see if all the items have been provided, and if not, this sends a Bad Request Response to the client.
Now you know about the JavaScript feature that failed, even after it had become a part of the specification. If you found this article useful, dropping a love react would make me happy. If you found some flaw in this article, please let me know in the comments below.
For articles and rants relating to JavaScript and Web Development, you may want to consider following me.
Top comments (1)
Wow didn't know about using
with
in js. I love learning about niche features. Pretty cool.Of course as is recommended I'll be sticking with es6 destructuring. :)