Внешний вид "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
окружающего внешнего объекта.
Что делать? спасибо
Ответы
Ответ 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);
...