Подтвердить что ты не робот

Внешний вид "this" в методе сортировки Javascript

У меня есть этот код:

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

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

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

Однако он не работает, я думаю, потому что this не может быть доступен в sort - там по какой-то причине видится другой this, а не this окружающего внешнего объекта.

Что делать? спасибо

4b9b3361

Ответ 1

Разный this заключается в том, что анонимная функция (ее собственное закрытие), вызываемая arr.sort, вызывает функцию с this, установленную на другой элемент, чем ваш основной объект. В Array.sort я действительно не уверен, что установлен this, но это, вероятно, массив, который вы сортируете. Обычная работа в этой ситуации заключается в использовании другой переменной:

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

Ответ 2

Вы можете привязать "внешний" экземпляр к "внутренней" функции, вызвав метод bind для внутренней функции. Подробнее читайте в MDN.

Пример: 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()

Ответ 3

Поскольку ваш алгоритм сортировки не зависит от чего-либо внутри do_something (кроме того, что предоставляется массивом), рассмотрите возможность перемещения функции вне 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);
   }
}

Или даже предложите простой factory, если вы выполните подобную сортировку в другом месте:

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