0

I'm using next jQuery plugin implementation for defining my plugins. I'm been using javascript for several years now, but javascript has so many surprises.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script src="jquery-3.3.1.js"></script>
    <script type="text/javascript">
    (function ($) {
      // is using $.fn best practise / ok? or is something else better
      // according to https://learn.jquery.com/plugins/basic-plugin-creation it's fine
      $.fn.myPlugin = function () {

        // private variables
        var instance = this;
        var privateVar1 = "some Value";

        // private methods
        var privateMethod = function(arg1) {

          var bla = privateVar1;

          if( arg1 > 0) {
            arg1 -= 1;
            // to call public method I just call:
            instance.publicMethod(arg1);
          }
        };

        // public methods start with this.
        this.initialize = function () {

          // this can refer to different things, depending on calling context
          // https://stackoverflow.com/questions/3562980/javascript-this-value-changing-but-cant-figure-out-why
          return this;
        };

        this.publicMethod = function(arg1) {
          debugger;

          // private methods are called only with the name
          privateMethod(arg1);
        };

         return this.initialize();
      }
    })(jQuery);


  $(document).ready(function() {    

     var a = $("#test").myPlugin();
     a.publicMethod(1);

  });
    </script>
  </head>

  <body>
    <div id="test">Test
       <div id="test1"></div> 
    </div>
  </body>
</html>

I want to make sure that there aren't any bugs. For example, I know this is changed based on context (Javascript 'this' value changing, but can't figure out why) ... Have I missed something?

The idea is to write custom plugins in the form like this:

$("#myList").myCredentialsDialog();
$("#cars").carsGrid();
...

Basically so that every custom plugin can use this template. The template means var instance = this, this.publicMethod, var privateMethod = function() ...

broadband
  • 3,266
  • 6
  • 43
  • 73

1 Answers1

1

You may confused by this context in javascript. You're right about this will change following the context, it will do if you use function() { } if you want this from outside of context then use () => { } instead.

I'm analyse your code and think it would not work. You can do public variable like this.

  <head>
    <meta charset="UTF-8">
    <script src="jquery-3.3.1.js"></script>
    <script type="text/javascript">
    (function ($) {
      // is using $.fn best practise / ok? or is something else better
      // according to https://learn.jquery.com/plugins/basic-plugin-creation it's fine
      $.fn.myPlugin = function () {

        // private variables
        var privateVar1 = "some Value";

        // private methods
        var privateMethod = (arg1) => {

          var bla = privateVar1;

          if( arg1 > 0) {
            arg1 -= 1;
            // to call public method I just call:
            this.publicMethod(arg1);
          }
        };

        // public methods start with this.
        this.initialize = () => {

          // this can refer to different things, depending on calling context
          // https://stackoverflow.com/questions/3562980/javascript-this-value-changing-but-cant-figure-out-why
          return this;
        };

        this.publicMethod = (arg1) => {
          debugger;

          // private methods are called only with the name
          privateMethod(arg1);
        };

         return this.initialize();
      }
    })(jQuery);


  $(document).ready(function() {    

     var a = $("#test").myPlugin();
     a.publicMethod(1);

  });
    </script>
  </head>

  <body>
    <div id="test">Test
       <div id="test1"></div> 
    </div>
  </body>
</html>

This code should work.

William Gunawan
  • 748
  • 3
  • 8
  • Cool, thnx are there any other observations or potential problems? So the only thing that should be changed is using lamba expressions `()` which changes the context? Are `()` supported by all browsers, I mean since ecma script ... – broadband Aug 02 '19 at 16:07
  • Yes. You can even do it without variable instance. that's why in google javascript guideline's must use lamba instead of function() so developer not confused by this context. – William Gunawan Aug 02 '19 at 16:26
  • Well the only problem is that `()` lambda (which equals anonymous functions) in javascript **is not supported in Internet Explorer**. Therefore function() must be used. - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Browser_compatibility – broadband Aug 02 '19 at 17:02
  • By 'you think it won't work', what exactly did you mean by that? – broadband Aug 05 '19 at 07:08
  • ` this.initialize = function () { return this; };` You return this in this.initialize = function (), this context is owned by function () not outside this. it will work if you return instance not return this – William Gunawan Aug 05 '19 at 07:12
  • So `var plugin = this; plugin.initialize = function() { //code .. return plugin; } ` In both cases the code works, it's just more safe to use `plugin/instance` – broadband Aug 05 '19 at 07:22
  • Yup. Avoid this context issue. Usually i use let fn = {}; then fn.Initialize, fn.WhateverFunction, by the end return fn. :) – William Gunawan Aug 05 '19 at 07:36