I'll be honest – I don't do much front-end stuff. I've watched the odd PluralSight course on modern JavaScript, I've worked out the basics of Gulp, and I can hack together a VueJS UI if I need to. But it's certainly not something I'd ever say I was good at. But despite being offically a C# developer, occasionally I find myself looking at bug tickets that relate to some front-end code. I had one of them this week, where some javascript had stopped working. The front-end dev was stuck, so I took a look – and discovered something new. Well new to me at least...
Stripping away all the client-specifc noise, what it basically consisted of was a chunk of data obtained from the back-end:
var dataSet = [ { name: "One A", data: "1" }, { name: "Two B", data: "2" }, { name: "Three C", data: "3" }, ];
Followed by some code that iterated this data, to do some processing and mapping. It happens that this code was recycled from elsewhere, and made use of jQuery. The actual processing logic doesn't matter here – but when I looked at the code, the iteration behaviour looked like this:
$.each(dataSet, function(item) { doSomething(item.name); });
That looked ok to me at first glance – and none of the other devs had spotted an issue – but overall the code was no longer working. The code in
doSomething()
would fail because the incoming parameter was undefined - despite the data clearly having the right property. What had gone wrong?
If you
look at the documentation for
.each()
on the jQuery site
then it talks about the function declared there taking two parameters:
functionAfter a bit of thinking that explained the issue for me: one of the previous commits in the project had removed an "unused" parameter from the inner function. When the code was working, it looked like:
Type: Function( Integer index, Element element )
A function to execute for each matched element.
$.each(dataSet, function(index, item) { doSomething(item.name); });
The integer
index
parameter wasn't being used, and the
item
parameter contained the expected object. But some over-zealous refactoring had removed the apparently unused parameter. I'm guessing some sort of
jshint
warning was being thrown up? And it was changed to:
$.each(dataSet, function(item) { doSomething(item.name); });
And jQuery / JavaScript didn't really care. The array index value was happily mapped into
item
and the array element had no parameter to be mapped into so was ignored. That meant any reference to
item.name
just returned nothing, as that property doesn't exist on an integer...
function test(x, y) { console.log("x: " + x); console.log("y: " + y); } test(10);
It may not be good code – but it runs without any errors. The parameter you omit is just passed as "undefined". No warnings in the console, no errors at runtime.
So mostly I learned that JavaScript is just flexible enough to let you reach down and shoot yourself in the foot...
↑ Back to top