2

I have the following code snippet:

MARKUP:

<tr name="tr3" id="tr3">
    <td>
        <input type="text" class="common_cls" name="dt[]" id="dt1"> 
    </td>
    <td>
        <input type="hidden" name="fn[]" id="fn1">
        <span id="sp1"><a href="#" id="ah1">choose file</a><span>
        <input type="file" name="fff[]" id="ff">
        <input type="text" style="display:none">
    </td>
</tr>';

JAVASCRIPT

$(document).on('click', '#add_row', function() {
    var row = $("table#DocTable tr:eq(3)");
    row.clone(true)
        .show()
        .find("a, input, span").each(function() {
            $(this)
                .val('')
                .attr('id', function(_, id) {
                    var newcnt = id + count;
                    return id + count;
                });
        })
        .end()
        .appendTo("table");
    count++;

I wrote this over a year ago and I had assistance with the bit in question.

What is the purpose of the underscore as the first argument of the function called in the .attr method?

How exactly does that function work? Does it just replace the current id in all a, span and input tags with an incremented number?

cssyphus
  • 37,875
  • 18
  • 96
  • 111

4 Answers4

5

The underscore is normally used as a placeholder for an unnamed variable. Basically, if you're not going to use that variable, there's no need to find a name for it, so you can just use an underscore instead.

Not to be confused with the i18n underscore function or underscore.js.

P.S.: I'm not sure where this practice comes from, but the first time I saw an underscore being used for something this was when I was learning Prolog (in which _ actually means something like "any value").

ubik
  • 4,440
  • 2
  • 23
  • 29
  • Why is that unused variable necessary? Why not just write `function(id){//blah blah blah}`? – cssyphus Apr 23 '13 at 21:01
  • @gibberish because the first parameter contains the index, and you want the value not the index. – Kevin B Apr 23 '13 at 21:02
  • 1
    @gibberish, you call your function arguments whatever you want, and the JS interpreter cannot guess that by `id` you actually mean the 2nd parameter and not the 1st. "Keyword arguments" are not supported in JS, unfortunately. – ubik Apr 23 '13 at 21:06
4

The index of the current element is stored in the _ in this case. All that function does is update the attribute of each element with that element's id + count. If you instead named it index or i you may have been able to guess that it contained the index..

Kevin B
  • 94,570
  • 16
  • 163
  • 180
3

There are many aspects associated with this answer, which are scattered over the comments and other answers. So, I'll try to consolidate them below:

Firstly, in the mentioned piece of code, the underscore argument is used as follows:-

$(this).val('').attr('id', function(_, id) { return id + i });

From the jQuery documentation for the attr function here, there exists an overloaded form of attr which is .attr( attributeName, function ). The function in this form is described as

Type: Function( Integer index, String attr )

Hence, it expects two parameters. However, in our code, we need only the id, which happens to be the second parameter.

Now, because of the way JS handles function arguments, we cannot write it as function(id), as JS would map id to index (the first argument expected for function). Thus, the function we write needs to have two parameters.

Here, a standard convention comes into play. As mentioned here,

The underscore character (_) is used as a standard way to indicate an unused function argument.

However, this is only a convention and not a rule. We could name the unused argument as index or unused just as well. That is,

$(this).val('').attr('id', function(unused, id) { return id + i });

would be a valid equivalent.

Thus, such a usage of _ to substitute for an unused argument can be used for any other jQuery function that has a similar overridden form. For example, in this answer, we can see the usage of underscore in the call to $.text(). Just to confirm, $.text() has an overridden form that accepts a function with two arguments, as shown here.

Community
  • 1
  • 1
Sarath Chandra
  • 1,850
  • 19
  • 40
0

Well, that can only be answered by the author. The _ there is the name of the first argument to the function.

Based on the code that I can see I'm guessing that the, since the _ variable is not used in the function at all, first argument isn't necessary in this function and so it's been "stubbed" out with an _ instead of a random name.

Brandon Buck
  • 7,177
  • 2
  • 30
  • 51