最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create proper closures in jQuery? - Stack Overflow

programmeradmin3浏览0评论

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 the input in the console, obviously. How can i get bar as this instead?

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 the input in the console, obviously. How can i get bar as this instead?

Share Improve this question edited Nov 8, 2016 at 9:46 n1313 asked Aug 26, 2009 at 18:53 n1313n1313 21.5k7 gold badges32 silver badges46 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

That happens because when you bind an event, the event handler function is called with the context of the DOM element which triggered the event, the this keyword represents the DOM element.

For getting "bar" you should store a reference to the outer 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
  }
};

Note: If the bar function is called without the new operator, this will be the window object and baz and foo will bee global variables, be carefull!

However I think your code can be simplified:

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
  }
};

to get bar in your foo do this:

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);
}

}

This is a general problem when using instance methods as callbacks in JavaScript. I use this function to create a closure to call the method bound to the correct instance:

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

Then you can use this as your callback in place of this.foo:

bound_method(this, this.foo)

Unlike some of the other proposals, this allows you to put the methods on the prototype instead of creating them in the constructor. This way you only have one shared copy of the implementation instead of re-creating those functions for each new instance of bar.

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);
  }
});

Here you go.this is an exmaple of how to get "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 happens because the function baz is called with an instance of bar.SO bar is executing within the "new bar()" context and not the window object.

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

发布评论

评论列表(0)

  1. 暂无评论