Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Javascript's _this, different types of function calls and how to call a function inside a function?

Tags:

javascript

I am learning how to reverse engineer an existing javascript code and I've ran into a few issues which is due to my lack of understanding how core javascript works. The code is below along with a screen shot of the comments I have.

The code starts out with var warper being declared.

  • And then warper variable equals a function inside a function? Why isn't it the usual call of function Warper(), but its inside another function?
  • I noticed the use of _this. How is that different from the regular this that is usually used?
  • The #btn-submit id is set to activate when it is clicked on. I can see that it calls the click_submit function, but why is it Warper.prototype.click_submit instead of just click_submit()?
  • And my final question, which is what I really want to do is call the click_submit function via js without having to click on the #btn-submit button.

Question: How do I call the warper.click_submit function using js without the need to click a button? I'm trying to integrate this into another piece of my code.

I tried warper.prototype.click_submit and it doesnt do anything. I'm assuming its because its inside a function in a function?

enter image description here

(function() {
  var Warper;

  Warper = (function() {
    function Warper() {
      this.check_compatibility();
      this.attach_ux();
      if (window.SALT_DEFAULT != null) {
        $('#salt').val(window.SALT_DEFAULT);
        $('#salt').attr('disabled', true);
        $('.salt-label').text('Prefilled salt');
      }
    }

    Warper.prototype.check_compatibility = function() {
      if (typeof Int32Array === "undefined" || Int32Array === null) {
        return $('.form-container').html('<p>\n  Sorry, but your browser is too old to run WarpWallet, which requires Int32Array support.\n</p>');
      }
    };

    Warper.prototype.attach_ux = function() {
      $('#btn-submit').on('click', (function(_this) {
        return function() {
          return _this.click_submit();
        };
      })(this));
      $('#btn-reset').on('click', (function(_this) {
        return function() {
          return _this.click_reset();
        };
      })(this));
      return $('.what-salt').on('click', (function(_this) {
        return function() {
          return $('.salt-explanation').toggle();
        };
      })(this));
    };


    Warper.prototype.click_submit = function() {
      $('#btn-submit').attr('disabled', true).html('Running...');
      $('#btn-reset').attr('disabled', true).html('Running...');
      $('#passphrase, #salt, checkbox-salt-confirm').attr('disabled', true);
      $('.progress-pbkdf2, .progress-scrypt').html('');
      $('.progress-form').show();
      return warpwallet.run({
        passphrase: $('#passphrase').val(),
        salt: $('#salt').val(),
        progress_hook: (function(_this) {
          return function(o) {
            return _this.progress_hook(o);
          };
        })(this),
        params: window.params
      }, (function(_this) {
        return function(res) {
          $('#passphrase, #checkbox-salt-confirm').attr('disabled', false);
          if (window.SALT_DEFAULT == null) {
            $('#salt').attr('disabled', false);
          }
          $('#private-key').val(res["private"]);
          _this.write_qrs(res["public"], res["private"]);
          return console.log;
        };
      })(this));
    }; //click_submit

    return Warper;

  })(); // Warper End

  $(function() {
    return new Warper();
  });

}).call(this); // End Function
like image 456
Patoshi パトシ Avatar asked Oct 28 '16 04:10

Patoshi パトシ


People also ask

How do you call a function inside a function?

To call a function inside another function, define the inner function inside the outer function and invoke it. When using the function keyword, the function gets hoisted to the top of the scope and can be called from anywhere inside of the outer function.

What is _this?

_this is just a variable that is set to point to outer this . Everytime you call a function it has own this (depending on how you called the function). So if define callback inside another function, and you need to refer to this of that outer ("another") function, you can save it temporarily to variable.

How do you call a function?

You call the function by typing its name and putting a value in parentheses. This value is sent to the function's parameter. e.g. We call the function firstFunction(“string as it's shown.”);


2 Answers

The code starts out with var warper being declared.

  • And then warper variable equals a function inside a function? Why isn't it the usual call of function Warper(), but its inside another function?

It is inside another function to create it's own scope. This practice is used mainly to separate non relative code and prevent global variables.

  • I noticed the use of _this. How is that different from the regular this that is usually used?

_this is just a variable that is set to point to outer this. Everytime you call a function it has own this (depending on how you called the function). So if define callback inside another function, and you need to refer to this of that outer ("another") function, you can save it temporarily to variable. This temporarily variables are usually referred to as _this, that or self.

  • The #btn-submit id is set to activate when it is clicked on. I can see that it calls the click_submit function, but why is it Warper.prototype.click_submit instead of just click_submit()?

If you define function on prototype, every instance will use that same function. If you would define it on this.clik_submit = function(){...} then every instance would have to have it's own copy of that function. Last option is to just define function click_submit(){...} inside scope, but then the function wouldn't be accessible from outside the scope.

  • And my final question, which is what I really want to do is call the click_submit function via js without having to click on the

    btn-submit button.

You need to gain access to warper instance to be able to call the click_submit function. Without it (and without being able to update the code) it is not possible to call it. But you could consider creating click event on button yourself which would trigger the function. Using jquery this is as easy as $("#btn-submit").click();

like image 153
Buksy Avatar answered Sep 21 '22 09:09

Buksy


Warper is an object.

Warper.prototype.attach_ux = function() {
  $('#btn-submit').on('click', (function(_this) { //2
    return function() {
      return _this.click_submit(); //3
  };
})(this));//1. 

on //1 'this' refers to the Warper object and is bound to the scope of Warper.prototype.attach_ux function.

on //2 _this is the name of argument which refers to the value passed at //1.

Since //1 refers to the Warper object the click_submit method is called.

This is IIFE pattern of function invocation. If you were to call

$('#btn-submit').on('click', function(_this) { 
    return function() {
      return _this.click_submit();
  };
})

Here _this would refer to the click event and we would not be able to access the defined method conviniently. But we are able to pass the Warper object using IIFE pattern and access it easily.

like image 28
avck Avatar answered Sep 18 '22 09:09

avck