1

I have been using jQuery for a year, but I still don't understand how this code works:

alert($('#elementID').val()); // It gets the value of element

$('#elementID').val('setting Value'); // the same function is setting value

some other functions of jquery also do the same like .html()

I want to know how this thing is achieved? How do they overload a javascript function?

Lucas
  • 16,930
  • 31
  • 110
  • 182
Rupesh Patel
  • 3,015
  • 5
  • 28
  • 49

5 Answers5

8

There are no overloads in javascript, so feats like this are performed using optional parameters. JavaScript allows you to call functions without specifying parameters. For example:

function val(text)
{
  if (arguments != null && arguments.length > 0) {
    alert("i'm setting value here to " + text);
  } else {
    alert("i'm getting value here");
  }
}

val(); // alerts value getter
val('hi!'); // alerts value setter and the message

This example was written to point out arguments collection which you get in every function. Every function can fetch it's parameters as a collection and can accordingly perform it's logic. However, displayed example would be written differently in real world:

function val(text)
{
  if (typeof text === "string") {
    alert("i'm setting value here to " + text);
  } else {
    alert("i'm getting value here");
  }
}

Each parameter which you do not pass to a function gets "value" of undefined (not null). This lets you use the shortest logical expression. You can use any value in if statement. Variables which are null or undefined will simply be evaluated as false.

As a comment below pointed out if text parameter is empty string if (text) would return false. For that reason, for text parameters check parameters by type.

It would be beneficial for you to also read about null and undefined differences.

Community
  • 1
  • 1
Nikola Radosavljević
  • 6,871
  • 32
  • 44
  • in your first code snippet var "arguments" is it a default keyWord? or where you defined it ? – Rupesh Patel Aug 25 '12 at 10:07
  • Arguments is default keyword. I also provided link to Mozilla Developer Network where you can read about it. – Nikola Radosavljević Aug 25 '12 at 10:08
  • @Rupesh: They wrote *"This example was written to point out [arguments](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments) collection which you get in every function. Every function can fetch it's parameters as as collection and can accordingly perform many operations."*. There is already a link (see the blue text?) that you can follow to learn more about `arguments`. – Felix Kling Aug 25 '12 at 10:09
  • 1
    Empty string and 0 are also evaluated as false, so in your second example you can't set value by calling `val(0)` – fdermishin Aug 25 '12 at 10:12
  • @RupeshPatel, here is a [link for arguments](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments). – The Alpha Aug 25 '12 at 10:25
5

It's simply done by checking if the function was called with a parameter or not

function stuff(moreStuff){
   if(typeof moreStuff === "undefined"){
      return originalStuff;
   }else{
      setStuff(moreStuff);
   }
}
Adi
  • 5,089
  • 6
  • 33
  • 47
  • so there is no overloading concept in JS but we can do some work around, Thanks for reply :) – Rupesh Patel Aug 25 '12 at 10:02
  • It is safe to write `if(moreStuff === undefined)` in this example because `moreStuff` is an argument. http://stackoverflow.com/questions/4725603 – fdermishin Aug 25 '12 at 10:25
3

Very simple, just check if the variable has a value:

function foo(param) {
    // Method 1
    if (param != null) {
        // Parameter is defined
    } else {
        // No parameter (or null given)
    }

    // Method 2
    if (arguments.length > 0) {
        // At least one argument has been defined
    }
}
Niko
  • 26,516
  • 9
  • 93
  • 110
  • 2
    +1 for the second option. But your `param != null` may not work as intended - see http://saladwithsteve.com/2008/02/javascript-undefined-vs-null.html – techfoobar Aug 25 '12 at 10:02
  • this doesn't work null will not match with param if called lie this foo() – Rupesh Patel Aug 25 '12 at 10:05
  • @techfoobar I'm aware of that, but the check as implemented in my code above simply allows only parameters that are not `undefined` and not `null`. – Niko Aug 25 '12 at 10:10
  • @RupeshPatel Yes, it will. If you do `foo()`, `param` will be `undefined` - and `undefined == null` is true. – Niko Aug 25 '12 at 10:11
  • @Niko As per I know undefined is the type and null is an object itself – Rupesh Patel Aug 25 '12 at 10:15
  • @RupeshPatel Yes, but that does not apply in this case. `typeof x;` yields "undefined" if you have never defined a variable "x" before. However, the variable that contains a function parameter ("param" in the above code) is always defined. If no value has been specified (`foo()` instead of `foo("bar")`), the value of that variable is `undefined` (that's a special value!). You can therefore access the variable without receiving a ReferenceError, what enables you to simply test for `!= null` - that way, you sort out both undefined and null values, because both are not real values. – Niko Aug 25 '12 at 10:23
1
function foo(value)
{
     if(typeof value != 'undefined')
     {
         // calling foo(2332)
     }
     else
     {
         // foo()
     }
}
Govind Malviya
  • 13,627
  • 17
  • 68
  • 94
1

As nearly everyone else mentioned, they did not overload the parameter, but in the first statement, there is not arguments provided for the function. In the second one though, an argument has been provided. Therefore a simple check typeof something == "undefined" could easily modify and set apart the different results.

This is the relevant jQuery code making up the .val() function (version 1.8.0):

val: function( value ) {
        var hooks, ret, isFunction,
            elem = this[0];

        if ( !arguments.length ) {
            if ( elem ) {
                hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];

                if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
                    return ret;
                }

                ret = elem.value;

                return typeof ret === "string" ?
                    // handle most common string cases
                    ret.replace(rreturn, "") :
                    // handle cases where value is null/undef or number
                    ret == null ? "" : ret;
            }

            return;
        }

        isFunction = jQuery.isFunction( value );

        return this.each(function( i ) {
            var val,
                self = jQuery(this);

            if ( this.nodeType !== 1 ) {
                return;
            }

            if ( isFunction ) {
                val = value.call( this, i, self.val() );
            } else {
                val = value;
            }

            // Treat null/undefined as ""; convert numbers to string
            if ( val == null ) {
                val = "";
            } else if ( typeof val === "number" ) {
                val += "";
            } else if ( jQuery.isArray( val ) ) {
                val = jQuery.map(val, function ( value ) {
                    return value == null ? "" : value + "";
                });
            }

            hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];

            // If set returns undefined, fall back to normal setting
            if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
                this.value = val;
            }
        });
    }
Lucas
  • 16,930
  • 31
  • 110
  • 182