1

I'm trying to dive into the src code of jQuery, and at the very beginning of the the src code in the development version(3.2.1) of jQuery we find:

( function( global, factory ) {
"use strict";
if ( typeof module === "object" && typeof module.exports === "object" ) {
    module.exports = global.document ?
        factory( global, true ) :
        function( w ) {
            if ( !w.document ) {
                throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
        };
} else {
    factory( global );
}

As far as my knowledge is concerned, I know that ternary operator comes after some condition, but here it comes after an assignment operator module.exports = global.document ?. Could you explain this? What it does in the context of the previous code?

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
Profess Physics
  • 317
  • 4
  • 11
  • 2
    ternary operator goes after anything really. If its not a boolean, it will be converted as such. So if global.document is null or undefined or "" or any other falsy value, it will be considered as false and if not, true – juvian May 31 '17 at 15:43
  • 1
    That means if global.document is true then module.exports is assigned global.document. If global.document is falsy then function( w ) is assigned to module.exports which is being exported – Chris May 31 '17 at 15:44
  • Possible duplicate of [How do you use the ? : (conditional) operator in JavaScript?](https://stackoverflow.com/questions/6259982/how-do-you-use-the-conditional-operator-in-javascript) – juvian May 31 '17 at 15:47

2 Answers2

4

The ternary operator allow to conditionally evaluate two expressions (the first in case of the condition is true, the second one otherwise).

module.exports = global.document ?
        factory( global, true ) :
        function( w ) {
            if ( !w.document ) {
                throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
        };

The assignment means that, the result of the conditional evaluation is assigned to module.export.

The ternary operator is a syntactic sugar and works like this:

function ternary_operator(condition, expression1, expression2) {
    if (condition) {
        return expression1;
    } else {
        return expression2;
    }
}

so you can translate the code to:

module.exports = ternary_operator(global.document,
        factory( global, true ),
        function( w ) {
            if ( !w.document ) {
                throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
        });

Please, pay attention to:

factory( global, true )

and

    function( w ) {
        if ( !w.document ) {
            throw new Error( "jQuery requires a window with a document" );
        }
        return factory( w );
    };

They are both expressions: the result of the activation of the factory function is an expression; the definition of a function value is an expression too.

Lazy evaluation

The function ternary_operator provides an eager ternary operator. The expressions are evaluated within the condition, and then one of them are returned. For example:

var l = ternary_operator(C, A, B);
1. evaluate C
2. evaluate A
3. evaluate B
4. activate function ternary_operator
5. assign to l the result of the function

Javascript ternary operator is lazy: that means that the condition is firstly evaluated, then just one of the other expression is evaluatued, gaining in terms of performance.

var l = C ? A : B;
1. evaluate C
2.1 if C is true evaluate A
2.2 if C is false evalutate B
3. assign to l the expression evaluated
Ilario Pierbattista
  • 3,175
  • 2
  • 31
  • 41
1
a=b?c:d;

In this case the ternary operator does not check for a=b but rather for b. Thats because the assignment operator has a higher operator predescendence than the ternary operator, for a good reason.

(a=b)?c:d;

In this case the ternary operator really tests for a=b. In this case it will store b in a and return this value.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151