How to create proper closures in jQuery?

This is an example of my code:

var bar = function() {

  this.baz = function() {
    this.input = $('.input');
    this.input.bind("keydown keyup focus blur change", this.foo);
  }

  this.foo = function(event){
    console.log(this);
  }

}

Clicking on my input gives me inputon the console, obviously. How can I get barboth thisinstead?

+3
source share
4 answers

This is because when you bind an event, the event handler function is called with the context of the DOM element that called event, the keyword thisrepresents the DOM element.

To get a bar, you must save the link to the external closure:

var bar = function() {
  var self = this;

  this.baz = function() {
    this.input = $('.input');
    this.input.bind("keydown keyup focus blur change", this.foo);
  }

  this.foo = function(event){
    console.log(this); // the input
    console.log(self); // the bar scope
  }
};

. bar new, this window baz foo , !

, :

var bar = {
  baz: function() {
    var input = $('.input');
    input.bind("keydown keyup focus blur change", this.foo);
  },

  foo: function(event){
    console.log(this); // the input
    console.log(bar); // reference to the bar object
  }
};
+5

foo:

bar = function() {

var me = this;

this.baz = function() {
    this.input = $('.input');
    this.input.bind("keydown keyup focus blur change", this.foo);
}

this.foo = function(event){
    // me, would be your bar object.
    console.log(me);
}

}
+1

JavaScript. , :

function bound_method(instance, method) {
  return function() {
    return method.apply(instance, arguments);
  };
}

this.foo:

bound_method(this, this.foo)

, . , .

var bar = function() {};
$.extend(bar, {
  baz: function() {
    this.input = $('.input');
    this.input.bind("keydown keyup focus blur change",
                    bound_method(this, this.foo));
  },

  foo: function(event) {
    console.log(this);
  }
});
+1

. , "this"

<html>
<head></head>
<script  type="text/javascript" src="jquery-1.3.2.min.js"></script>

<script>
 var  bar = function() {

this.baz = function() {
    this.input = $('.input');
    this.input.bind("keydown keyup focus blur change", this.foo);
}

this.foo = function(event){
    console.log(this);
}

}

</script>
<body>
<input class="input">
<button onclick="new bar().baz()">Click</button>
</body>
</html>

This is because the baz function is called with an instance of bar.SO bar is executed in the context of "new bar ()", and not in the window object.

If you use firebug (it seems so), you can track logging as you type inside the input text control before and after clicking a click on the console tab.

0
source

Source: https://habr.com/ru/post/1716139/


All Articles