Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript - what is the purpose of declaring a variable a function first? (declaring variable twice)

Here is the code I have encountered:

    var c = function() {},
        c = {
            autoSelectFirst: !1,
            appendTo: "body",
            serviceUrl: null,
            lookup: null,
            .. etc..
            lookupFilter: function(a, b, c) {
                return -1 !== a.value.toLowerCase().indexOf(c)
            },
            .. etc..
        };

Why is c first declared as an empty function then re-declared as an object? Doesn't that just overwrite the function declaration? I suppose it is a fundamental JS construct.

like image 988
Oliver Williams Avatar asked Jan 06 '23 03:01

Oliver Williams


2 Answers

I found the file in question online, and it turns out there's a good reason for this.

First of all, it should be noted that the code in the question is from a minified source that has been indented.

Here's a chunk of the code:

var c=function(){},c={autoSelectFirst:!1,appendTo:"body",serviceUrl:null,lookup:null,
onSelect:null,width:"auto",minChars:1,maxHeight:300,deferRequestBy:0,params:{},
formatResult:g.formatResult,delimiter:null,zIndex:9999,type:"GET",noCache:!1,
onSearchStart:c,onSearchComplete:c,onSearchError:c,
// -----------^------------------^---------------^

So this is the code in the question, but a little more of it. The important thing to notice is that the variable c is used in the creation of the object literal, with onSearchStart:c,onSearchComplete:c,onSearchError:c,.

So which value is c assigning in the object? Because the object is still in the process of being created, that means c is still referencing the function, so properties like onSearchStart, which seem to be event handlers are getting the empty function as a default.

This makes much more sense.

To verify, I also found the original, unminified source. Here's the related code:

//   v---originally it's called `noop`
var noop = function () { },
    that = this,
    defaults = {
        autoSelectFirst: false,
        appendTo: 'body',
        serviceUrl: null,
        lookup: null,
        onSelect: null,
        width: 'auto',
        minChars: 1,
        maxHeight: 300,
        deferRequestBy: 0,
        params: {},
        formatResult: YithAutocomplete.formatResult,
        delimiter: null,
        zIndex: 9999,
        type: 'GET',
        noCache: false,
        onSearchStart: noop,    // <---here it's being used
        onSearchComplete: noop, // <---here it's being used
        onSearchError: noop,    // <---here it's being used

So it's clearer now that the noop, which generally stands for no-operation, has its own name and is indeed being used in the object being created just below it. Also, this is the only place noop is used in the entire file.

So apparently the minifier was clever enough to see that the variable originally called noop was not going to be used any longer, so it was free to reuse that variable name for the object. An impressive bit of code analysis, IMO.

like image 61
2 revsuser1106925 Avatar answered Jan 26 '23 22:01

2 revsuser1106925


Based on this code example from the original question:

var c = function() {},
    c = {
        autoSelectFirst: !1,
        appendTo: "body",
        serviceUrl: null,
        lookup: null,
        .. etc..
        lookupFilter: function(a, b, c) {
            return -1 !== a.value.toLowerCase().indexOf(c)
        },
        .. etc..
    };

The c = function() {}, part in the code that is included in your question has no point. It's like doing:

var x = 1, x = 3;

There's no point in assigning one value to the variable and then immediately assigning another value to it.

The code you show would generate the exact same result (with less confusion) as this:

    var c = {
        autoSelectFirst: !1,
        appendTo: "body",
        serviceUrl: null,
        lookup: null,
        .. etc..
        lookupFilter: function(a, b, c) {
            return -1 !== a.value.toLowerCase().indexOf(c)
        },
        .. etc..
    };

Based on the comments for where this code was found, it appears that it is part of some automatic code generation or minimization process.

FYI, Javascript does not use the phrase "associative array". The second declaration is a Javascript object.

like image 38
jfriend00 Avatar answered Jan 26 '23 20:01

jfriend00