开发者

access outer "this" in Javascript sort method

开发者 https://www.devze.com 2022-12-19 23:54 出处:网络
I have this code: function some_object(...) { this.data = {...}; this.do_something = function(...) { var arr = [...];

I have this code:

function some_object(...) {
   this.data = {...};

   this.do_something = function(...) {
      var arr = [...];

      arr.sort(function (a, b) {
         return this.data[a] - th开发者_如何学Gois.data[b];
      });  
   }
}

However it's not working I think because this cannot be accessed in sort - another this is seen there for some reason, not the this of enclosing outer object.

What to do? thanks


The different this is because the the anonymous function (its own closure) called by arr.sort calls the function with this being set to a different item than your main object. In an Array.sort, I am not actually sure what this is set to, but it is probably the Array you are sorting. A normal work around in this situation is to use another variable:

function some_object(...) {
   var so = this; // so = current `this`
   this.data = {...};

   this.do_something = function(...) {
      var arr = [...];

      arr.sort(function (a, b) {
         return so.data[a] - so.data[b];
      });  
   }
}


You can bind the "outer" instance to the "inner" function by invoking the bind method on the inner function. Learn more at MDN.

Example: https://jsfiddle.net/eheobo/twv3emh7/1/

var foo = {
    data: [1, 2, 3, 4],
    bar: function () {
        var printData = function(){
            this.data.forEach(a => console.info(a))
        }.bind(this)
        printData()
    }
}

foo.bar()


I know this is a question from 2010, but now you should probably use arrow functions (and classes):

class some_object {
  constructor() {
    this.data = {...};
  }
  do_something(...) {
    let arr = [...];
    arr.sort((a, b) => this.data[a] - this.data[b]);
  }
}

Arrow functions don't have a this, so they use the one from the enclosing scope.


Since your sort algorithm doesn't depend on anything within do_something (other than that provided by the array), consider moving the function outside of do_something:

function some_object(...) {
   var so = this;
   so.data = {...};
   var comparator = function(a,b) { return so.data[a] - so.data[b]; };

   this.do_something = function(...) {
      var arr = [...].sort(comparator);
   }
}

Or, even provide a simple factory if you do this kind of sorting elsewhere:

var comparatorFactory = function(data) { return function(a,b) { return data[a] - data[b]; } };
function some_object(...) {
   var so = this;
   so.data = {...};
   var comparator = comparatorFactory(so.data);
   ...
0

精彩评论

暂无评论...
验证码 换一张
取 消