-1

I am new to javascript. Can somebody explain me what this below code does. It not seems like regular javascript. Is this uses any framework like node.js or underscore.js?.

What do 'exports and other functions do here. Just give me a brief idea about this library file.

(function (exports, global) {

    "use strict";

    var _ = {};
    exports.internal = _;

    exports.debugLogEnabled = true;

    _.debug = function (x) {
        if (exports.debugLogEnabled) {
            console.log(x);
        }
    };

    _.removeAllElements = function (array) {
        array.length = 0;
    };

    _.addElements = function (array, elements) {
        elements.forEach(function (element) {
            array.push(element);
        });
    };

    _.contains = function (array, element) {
        return array.indexOf(element) >= 0;
    };

    _.isUndefined = function (x) {
        return typeof(x) === 'undefined';
    };

    _.setDefault = function (obj, key, defaultValue) {
        if (_.isUndefined(obj[key])) {
            obj[key] = defaultValue;
        }
    };

    _.forKeyValue = function (obj, f) {
        var key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                f(key, obj[key]);
            }
        }
    };

    _.merge = function (obj, defaults) {
        _.forKeyValue(defaults, function (key, value) {
            _.setDefault(obj, key, value);
        });
    };

    };
})(typeof exports === 'undefined' ? this.sec = {} : exports, this);
user2613946
  • 435
  • 2
  • 7
  • 17
  • One thing I can understand is that you are either using [underscorejs](http://underscorejs.org/) or [lowdashjs](https://lodash.com/). All those underscores (`_.setDefault`) being used in your code are indicative of it. – RBT Jul 21 '17 at 05:12
  • They look javascript to me. Nothing special here. It looks like an utility module for manipulating javascript `array` – Samuel Toh Jul 21 '17 at 05:16
  • There is nothing special going on and no libraries being used. Try replacing "_" everywhere with "myObj" and it may be come much clearer. – RobG Jul 21 '17 at 05:29

2 Answers2

0

This is all native javascript. There is no evidence of any external javascript library being used in the code you have shared in your post.

Your function is actually an Immediately Invoked Function Expression (IIFE) as described here.

Quoting from the link:

It executes immediately after it’s created. This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.

RBT
  • 24,161
  • 21
  • 159
  • 240
  • 1
    The third line of code is `var _ = {};`. I suggest that the underscore is being used here as a convention to indicate a "private" variable, not the use of lodash.js or underscore.js libraries. – RobG Jul 21 '17 at 05:26
  • But they have used 'exports' which is from node.js right? – user2613946 Jul 21 '17 at 05:36
  • @user2613946—it doesn't need a special "exports" value. If it's not available, it just creates a global *sec* and assigns an empty object. So not dependent on node.js either. – RobG Jul 21 '17 at 05:47
  • export feature came up ECMA script v6 (aka ECMA 2015). Your function `function (exports, global)` is using `exports` as parameter which is simply the name of the parameter and nothing else. You are confusing it with `export` (without s in the end) keyword in javascript which is a reserved keyword. You can check more about exporting a module [here](https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export). – RBT Jul 21 '17 at 05:47
  • @RobG you are correct. Updated my post to reflect the same. – RBT Jul 21 '17 at 05:58
  • @RBT: Thanks for your great help! – user2613946 Jul 21 '17 at 06:16
0

This style is called an immediately invoked function expression (IIFE).

The first line:

(function (exports, global) {

is the start of a function expression that takes two arguments and assigns the first to a variable named "exports" and the second to a variable named "global". These variables are only available within the function (i.e. they're local variables).

Now skip to the last line to see how the function is called:

})(typeof exports === 'undefined' ? this.sec = {} : exports, this);

This calls the IIFE and passes two values, the first is the result of evaluating:

typeof exports === 'undefined' ? this.sec = {} : exports

which is a use of the conditional ? : operator (aka "ternary operator"). The expression typeof exports === 'undefined' is evaluated, and if it returns true (i.e. there is no global variable "exports") then the expression:

this.sec = {}

is evaluated and the result returned. Since it's global code, this references the global (window in a browser) object and expression creates a property named "sec" and assigns it an empty object. This value (i.e. a reference to the empty object) is then passed as the first value in the call.

If the expression returns false (i.e. the global "exports" is not undefined), then its value is passed as the first value in the call.

The second value passed is this, which as already mentioned is a reference to the global object.

So when the function is executed, exports references an object and global references the global object.

The rest should be pretty straight forward. Perhaps replace "_" everywhere with "myObj", so:

var _ = {};
exports.internal = _;

becomes:

var myObj = {};
exports.internal = myObj;

It could be written as a single initialiser :

var myObj = {
  debug: function (x) {
    if (exports.debugLogEnabled) {
        console.log(x);
  },
  removeAllElements: function (array) {
    array.length = 0;
  },
  // and so on...
};

exports.internal = myObj;
exports.debugLogEnabled = true;
RobG
  • 142,382
  • 31
  • 172
  • 209