2

I was just going through Chris Coyer's examples of custom events, and came across the following code:

$.fn.faq = function(options) {

    return this.each(function(i, el) {

      var base = el,
              $base = $(el);

          console.log(options);

      base.init = function() {
        // Do initialization stuff
            $base
               .find("dd")
               .hide()
               .end()
               .find("dt")
               .click(function() {

                 var ans = $(this).next();

                 if (ans.is(":visible")) {
                   base.closeQ(ans); 
                 } else {
                   base.openQ(ans); 
                 }

               })
      };

      base.openQ = function(ans) {
        // Open panel
                ans.show();

        // Do callback
        options.qOpen.call();
      };

      base.closeQ = function(ans) {
        // Open panel
                ans.hide();

        // Do callback
        options.qClose.call();
      };

      base.init();

    });

};

$("dl").faq({
  qOpen: myQuestionOpenCallback,
  qClose: myQuestionCloseCallback
});

function myQuestionOpenCallback() {
  alert("answer opened!");
}

function myQuestionCloseCallback() {
  alert("answer closed!");
}

I am refering to Chris Coyer's post:

Custom event by Chris Coyer

Fiddle here

Now my question is why is in this code the JavaScript call() is obviously not being used to set the value of this, so why is call being used? Is it a good JS practice ? or is it just a author choice, because if I take off call on both the below lines of code I.E. :

options.qOpen.call();

options.qClose.call();

if changed to

options.qOpen();

options.qClose();

My plugin still works fine, so why the use of call()?

I am new to JS and jQuery.

halfer
  • 19,824
  • 17
  • 99
  • 186
Alexander Solonik
  • 9,838
  • 18
  • 76
  • 174
  • @Karl-Andre Gagnon , Did you even bother to check the answer on that question before marking mine as a duplicate , the answer in that question , makes absolutly , no sense in context of my question, which brings me to my secound point , my question was more contextual , based on a famious article by one of the webs most followed developer . KevinB's answer makes sense and is entirely different from JonnyP's answer ... Again , because my question had a specific context . with that i rest my defence . – Alexander Solonik Mar 20 '15 at 21:08
  • You fooled me. That's not a fiddle! – Kevin B Mar 20 '15 at 21:10
  • @KevinB , tat was't my intention ;) LOL – Alexander Solonik Mar 20 '15 at 21:13
  • @AlexanderSolonik no need to take a duplicate vote as an offence. Before your edit, both questions were the same, just different context. before Kevin edited his answer, it was saying the exact same things as Jonny. So yeah, that close reason was good. Then, as said in the message, *"If those answers do not fully address your question, please ask a new question."* It said ask a new question, but honestly, I prefer you editing it. Now, the questions are not the same. Simply tagging me with `@` saying you edited the question would have been enough. – Karl-André Gagnon Mar 21 '15 at 01:38
  • @AlexanderSolonik After all that talk, I totally forgot to reopen the question. Not that it matter much since you got your answer, but still. Have a good day. – Karl-André Gagnon Mar 21 '15 at 16:05
  • @Karl-AndréGagnon , nvm and wish you the same :) – Alexander Solonik Mar 23 '15 at 05:42

1 Answers1

1

It simply prevents the functions passed as callbacks to the options object from modifying or accessing the options object.

function myQuestionOpenCallback() {
  alert("answer opened!");
  console.log(this); // window
}

function myQuestionCloseCallback() {
  alert("answer closed!");
  console.log(this); // window
}

Without .call(), it would be this:

function myQuestionOpenCallback() {
  alert("answer opened!");
  console.log(this); // {qOpen: function, qClose: function}
}

function myQuestionCloseCallback() {
  alert("answer closed!");
  console.log(this); // {qOpen: function, qClose: function}
}

I see no reason to do this (in your specific case) since the person using the plugin already has full access to said options object.

var opts = {
  qOpen: myQuestionOpenCallback,
  qClose: myQuestionCloseCallback
}
$("dl").faq(opts);
function myQuestionOpenCallback() {
  alert("answer opened!");
  console.log(opts); // {qOpen: function, qClose: function}
}

function myQuestionCloseCallback() {
  alert("answer closed!");
  console.log(opts); // {qOpen: function, qClose: function}
}
Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • are't you contradicting yourself in your second statement ? , also can you be a bit more elaborate with your first point of 'not being able to modify the object' ... that sounds interesting to me . – Alexander Solonik Mar 20 '15 at 20:58
  • Basically, if he didn't use `.call()`, `this` would be the options object, so you would be able to modify it. However, since the options object is being passed in as an object, the dev could have simply stored it in a variable and passed it by reference, so he would still have full access to it outside. – Kevin B Mar 20 '15 at 20:59
  • @AlexanderSolonik Updated answer with examples. – Kevin B Mar 20 '15 at 21:04