0

I have wrote a function which binds a behavior to an element. Let's say we have two inputs. Then we want to be able to show hints on these input so,

function ElementHinter(element){
  element.showNotice = function( message, type) {
    var errorBorderStyle = "1px solid #cc3e22";
    var warningBorderStyle = "1px solid #cc9322";

    var parent = element.parents('.value');
    element.css("border", type == element.ERROR ? errorBorderStyle : warningBorderStyle);
    if (!parent.find('.error-message').length) {
      messagePublisher(message, type);
    }   
  }

  element.removeNotice = function() {
    element.css("border-color", "#aaa #c8c8c8 #c8c8c8 #aaa");
    element.parents('.value').find('.error-message').remove();
  }


  var messagePublisher = function(message, type) {
    var parent = element.parents('.value');
    var errorStyle = "#cc3e22";
    var warningStyle = "#cc9322";

    var html = "<span class='error-message'>" + message + "</span>";
    parent.css("color", type == ElementHinter.ERROR ? errorStyle : warningStyle);
    jQuery(parent).append(html);
  }
  return element;
}

ElementHinter.ERROR = "ERROR"
ElementHinter.WARNING = "WARNING"

var priceElement    = ElementHinter($('input#price'));
var discountPercent = ElementHinter($('input#discount'));

priceElement.showNotice("Bad price friend",ElementHinter.WARNING);
discountPercent.showNotice("Bad discount friend",ElementHinter.WARNING);

Now, if I get rid of the var in the messagePublisher both notices will be shown on just one element. Why that happens? if I get rid of the var what does element mean in that context?

shampoo
  • 1,173
  • 12
  • 22
  • do you understand what global variable is? – dfsq Apr 12 '17 at 14:45
  • Check [Variable scope in Javascript](https://learn.microsoft.com/en-us/scripting/javascript/advanced/variable-scope-javascript). – Oen44 Apr 12 '17 at 14:48
  • @dfsq yes I do, the question is when the function is global how `element` is interpreted. – shampoo Apr 12 '17 at 14:49
  • 1
    In JavaScript 'var' will define new variable with visibility of current function. It is very new variable each time you call the function. When you declare variable without 'var' keyword, it becomes part of 'window' object (which is global root object). So when you call same function again, the variable already exists. TL;DR: always use 'var'. If in some case you think you don't need it, use 'window.your_var' expression, so you explicitly saying so. – Yuriy Grinevich Apr 12 '17 at 14:51
  • I have edited the question title. This is is not explained in the question marked as exact duplicate. – shampoo Apr 12 '17 at 14:55

1 Answers1

1

Without var, the variable becomes global. Thus, without var, there's only one messagePublisher variable and it's shared by all instances. It's as if you had the declaration:

var messagePublisher;

outside your function.

If you get in the habit of starting your script files or functions with the statement:

"use strict";

(exactly like that), then you'll get an error if you leave off var (or let or const in newer JavaScript).

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks. So, this is kind of bad practice right? Do you think the idea is generally good? To bind behaviors on elements like this? – shampoo Apr 12 '17 at 14:59
  • 1
    @shampoo well, in this case you're not really binding to the *element*, you're binding to a jQuery object. Another approach would be to create those functions as your own extensions to jQuery, which would let you write `$("input#price").showNotice();` – Pointy Apr 12 '17 at 15:05