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

javascript - Access to class member within closure - Stack Overflow

programmeradmin0浏览0评论

I have a class method and a closure within this method. How I can access to class member from closure?

Person = function(x) {
  this.x = x;
}

Person.prototype = {
   myMethod: function() {
      $('#myBtn').click( function() {
         // how to access to this.x? the this reference points in another context 
      });
   }
}

I have a class method and a closure within this method. How I can access to class member from closure?

Person = function(x) {
  this.x = x;
}

Person.prototype = {
   myMethod: function() {
      $('#myBtn').click( function() {
         // how to access to this.x? the this reference points in another context 
      });
   }
}
Share Improve this question edited Sep 1, 2013 at 18:51 WeleTo asked Sep 1, 2013 at 18:40 WeleToWeleTo 20.6k56 gold badges176 silver badges290 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 9

Use of Function.prototype.bind will help you here

Person = function(x) {
  this.x = x;
}

Person.prototype.myMethod = function() {
  $('#myBtn').click(function() {
    this.x;
  }.bind(this));
};

You can use some better separation of code here too

Person = function(x) {
  this.x = x;
};

Person.prototype.myMethod = function {
  $('#myBtn').click(this.clickHandler.bind(this));
};

Person.prototype.clickHandler = function(event) {
  console.log(this.x);
};

Note if you want to support older browsers, check out es5-shim


EDIT

I'm revisiting this after ~6 months and I would probably write the above code differently. I like the private/public exposure here. Also, no need for any fanciful binds or anything like that ^.^

function Person(x, $button) {

  // private api
  function onClick(event) {
    console.log(x);
  }

  function myMethod() {
    $button.click();
  }

  // exports
  this.x        = x;
  this.myMethod = myMethod;

  // init
  $button.click(onClick);
}

var b = $("#myBtn"),
    p = new Person("foo", b);

p.x;          // "foo"
p.myMethod(); // "foo"
btn.click();  // "foo"

Just assign this to some other variable, for example _this:

Person = function(x) {
    this.x = x;
}

Person.prototype = {
    myMethod: function() {
        var _this = this;
        $('#myBtn').click( function() {
            console.log(_this.x);
        });
    }
}
Person = function(x) {
  this.x = x;
}

Person.prototype = {
   myMethod: function() {
      var self = this;
      $('#myBtn').click( function() {
         // Access to self.x 
      });
   }
}

A proxy would be very useful here.

Right now, you're assigning an anonymous function to the click event. By default the context will be the event's and separate from your object.

With a proxy you can assign a particular context to a (callback) function. Thus, when the event fires, you're dealing with your person object.

  1. Assign the event handler in a separate function like initialize(), and have myMethod() be the handler.
  2. Use a JQuery.proxy() to assign the object`s context to the event handler.

    Person.prototype = {
        initialize: function() {
            $('#myBtn').click($.proxy(this.myMethod, this));
        },
    
        myMethod: function(event) {
         ...
         console.log(this); // Person object
        }
    }
    

Just to elicit the difference between my and @naomik's solution:

  • JQuery.proxy() is a temporary or narrow assignment to a context.
  • Function.prototype.bind() is a strong context assignment. The method will be "forever" bound to the context you give it.
发布评论

评论列表(0)

  1. 暂无评论