5 ways to call functions in JavaScript

  • 2020-05-16 06:17:03
  • OfStack

This article introduces the methods and principles of various function calls in Javascript in detail, which is of great help to understand the functions of JavaScript!

JavaScript, 5 ways to call a function

Time and time again, I've found that Javascript code with bug is the result of not really understanding how Javascript functions work (by the way, I wrote a lot of that code).

As a beginner, let's test 5 methods of function invocation. On the surface, we'll assume that those functions are very similar to the functions in C#, but as we'll see in a moment, there are some very important differences. Ignoring these differences will undoubtedly lead to the hard-to-trace bug. First, let's create a simple function, which will be used in the next article, that simply returns the current this value and two supplied parameters.


<script type="text/javascript">
function makeArray(arg1, arg2){
    return [ this, arg1, arg2 ];
}
</script>

The most common method, but unfortunately, is the global function call
When we learned about Javascript, we learned how to define functions using the syntax in the example above.
, we also know that calling this function is very simple, all we need to do is:


makeArray('one', 'two');
// => [ window, 'one', 'two' ]
 
Wait a minute. What's that window
 
 
alert( typeof window.methodThatDoesntExist );
// => undefined
alert( typeof window.makeArray);
// =>
 
 
window.makeArray('one', 'two');
// => [ window, 'one', 'two' ]

I say that the most common method of calling is unfortunate because it causes the functions we declare to be global by default. We all know that global members are not programming best practices. This is especially true in JavaScript, and you won't regret avoiding global members in JavaScript.

The JavaScript function calls rule 1
In a function that is called directly without an explicit owner object, such as myFunction(), the value of this becomes the default object (the window in the browser).

A function call

Let's now create a simple object and use the makeArray function as one of its methods. We'll declare an object using json, and we'll call this method as well


//creating the object
var arrayMaker = {
    someProperty: 'some value here',
    make: makeArray
};
 
//invoke the make() method
arrayMaker.make('one', 'two');
// => [ arrayMaker, 'one', 'two' ]
// alternative syntax, using square brackets
arrayMaker['make']('one', 'two');
// => [ arrayMaker, 'one', 'two' ]

See the different, this values into the object itself. You may doubt the original function definition does not change, why is it not window? Well, this is the way of function in JSavacript pass, function is a standard data types in JavaScript, precisely, an object. You can pass them or copy them. As if the whole function parameter list and the body of the function are to be copied, and assigned to the attribute make arrayMaker, it's like this definition 1 arrayMaker:


var arrayMaker = {
    someProperty: 'some value here',
    make: function (arg1, arg2) {
        return [ this, arg1, arg2 ];
    }
};

JavaScript function call rule 2

The value of this is obj when a method call syntax is used, such as obj.myFunction () or obj['myFunction']()

This is the main source of bug in event handling code. Take a look at these examples


<input type="button" value="Button 1" id="btn1"  />
<input type="button" value="Button 2" id="btn2"  />
<input type="button" value="Button 3" id="btn3"  onclick="buttonClicked();"/>
 
<script type="text/javascript">
function buttonClicked(){
    var text = (this === window) ? 'window' : this.id;
    alert( text );
}
var button1 = document.getElementById('btn1');
var button2 = document.getElementById('btn2');
 
button1.onclick = buttonClicked;
button2.onclick = function(){   buttonClicked();   };
</script>

Click the first button will display "btn" because it is a method call, this as subordinate to the object (button) click the second button will display "window" because buttonClicked was called directly (unlike obj. buttonClicked ().) this and our third button, the event handler directly in the label is 1 sample. So click the third button and the second is the result of the 1 sample.
Using an JS library like jQuery has the advantage that when an event handler is defined in jQuery, the JS library will help override the this value to ensure that it contains a reference to the current event source element,


// use jQuery
$('#btn1').click( function() {
    alert( this.id ); // jQuery ensures 'this' will be the button
});

How does jQuery overload this? Continue reading

The other two :apply() and call()

The more you use JavaScript function, and the more you find you need to transfer function call them in a different context, like Qjuery do 1 sample in the event handler, you often need to reset this value often. Remember what I told you, and in the Javascript function and object, function object contains 1 some predefined methods, there are two is apply () and call (), we can use them to reset this.


var gasGuzzler = { year: 2008, model: 'Dodge Bailout' };
makeArray.apply( gasGuzzler, [ 'one', 'two' ] );
// => [ gasGuzzler, 'one' , 'two' ]
makeArray.call( gasGuzzler,  'one', 'two' );
// => [ gasGuzzler, 'one' , 'two' ]

The two methods are similar except for the following parameters. Function.apply () is passed to the function using an array, while Function.call () is passed independently of these parameters. In practice, you will find apply() is more convenient in most cases.

The JSavacript function calls rule 3

If we want to overload the value of this without copying the function to a method, we can use myFunction.apply (obj) or myFunction.call (obj).

The constructor

I don't want to study in Javascript type's definition, but at the moment we need to know that there is no class in Javascript, and any one custom types require a initialization function, using the prototype object (as an initialization function of one attribute) defines the type of you is a good, let's create a simple type


// The statement 1 A constructor
function ArrayMaker(arg1, arg2) {
    this.someProperty = 'whatever';
    this.theArray = [ this, arg1, arg2 ];
}
// Declare the instantiation method
ArrayMaker.prototype = {
    someMethod: function () {
        alert( 'someMethod called');
    },
    getArray: function () {
        return this.theArray;
    }
};
 
var am = new ArrayMaker( 'one', 'two' );
var other = new ArrayMaker( 'first', 'second' );
 
am.getArray();
// => [ am, 'one' , 'two' ]

A very important and it is worth noting that appeared in front of the function call new operator, without that, you function as global function 1 sample, and we create those attributes will be created on the global object (window), and you don't want to do, the other is a topic, because there are no return values in your constructor, so if you forget to use new operator, will cause you some variables are assigned a value of 1 undefined. For this reason, it is a good practice to start the constructor with a capital letter as a reminder not to forget the previous new operator when calling.

With this care, the code in the initialization function is similar to the initialization function you write in other languages. The value of this will be the object you will create.

Javascript function call rule 4

When you use functions as initializers, such as MyFunction(), the Javascript runtime specifies the this value as the new object.

I hope understanding the different methods of function calls will keep your Sjavacript code away from bugs, and some of these bug will make sure you always know the value of this to avoid them step 1.


Related articles: