2016-04-24 4 views
0

У меня возникают проблемы с переносом моего мозга вокруг проблемы с использованием функции прототипа в массиве при ее сортировке. Я могу заставить его работать с статическим элементом, но когда я пытаюсь обобщить работу над массивом, я начинаю видеть ошибки «не является функцией». Вот мое текущее исполнение кода. Любая помощь будет оценена по достоинству.Доступ к функции прототипа при сортировке массива?

function Automobile(year, make, model, type) { 
    this.year = year; //integer (ex. 2001, 1995) 
    this.make = make; //string (ex. Honda, Ford) 
    this.model = model; //string (ex. Accord, Focus) 
    this.type = type; //string (ex. Pickup, SUV) 

} 
Automobile.prototype.logMe = function(bool) { 

    console.log("Working"); //testing function 
    if (bool == true) { 
     console.log(this); 
    } 

}; 

/*Sample Array*/ 
var automobiles = [ 
    new Automobile(1995, "Honda", "Accord", "Sedan"), 
    new Automobile(1990, "Ford", "F-150", "Pickup"), 
    new Automobile(2000, "GMC", "Tahoe", "SUV"), 
    new Automobile(2010, "Toyota", "Tacoma", "Pickup"), 
    new Automobile(2005, "Lotus", "Elise", "Roadster"), 
    new Automobile(2008, "Subaru", "Outback", "Wagon") 
]; 

/*This function sorts arrays using an arbitrary comparator.*/ 
function sortArr(comparator, array) { 


    array.sort(function(a, b) { 
     return comparator(a, b); 
    }); 
    return array; 
} 

function exComparator(int1, int2) { 
    if (int1 > int2) { 
     return true; 
    } else { 
     return false; 
    } 
} 


function yearComparator(auto1, auto2) { 
    return exComparator(auto1.year, auto2.year); 
} 

/* Output*/ 
console.log("*****"); 
console.log("The cars sorted by year are:"); 
forEach(sortArr(yearComparator, automobiles), automobiles.logMe(true)); //This is not right! 


function forEach(array, doStuff) { 
    for (var i = 0; i < array.length; i++) 
     doStuff(array[i]); 
} 
+2

Функции компаратора сортировки не должны возвращать только «истинные» или «ложные». Вместо этого они должны возвращать отрицательное число, ноль или положительное число, чтобы указать, что первое значение должно идти до другого, если они одинаковы или что второе значение должно идти до первого. – Pointy

+2

также, ваша функция sortArr _ функционально идентична_ 'array.sort (компаратор)' – Alnitak

+0

[Ваша функция сравнения недействительна] (http://stackoverflow.com/q/24080785/1048572), но это не проблема «иметь с« forEach ». – Bergi

ответ

1

Ваша сообщили, что проблема не имеет ничего общего с сортировкой (хотя ваша функция сортировки компаратора также недействительна - см. Ниже)

ошибки вы получаете, потому что вы Проходя мимо результата от automobiles.logMe к вашей forEach функции вместо ссылки на эту функцию. В любом случае эта функция logMe представляет собой общий метод и не может быть через массив.

Ваша функция сортировки и ненужно - весь ваш цикл сортировки/дисплей может быть написано:

automobiles.sort(yearComparator).forEach(function(auto) { 
    auto.logMe(true); 
}); 

, а затем вырезать ненужные sortArr и forEach функции, которые просто дублируют стандартные функциональные возможности ES5.

Чтобы исправить компаратор, ему необходимо вернуть один из (-ve, 0, + ve), а не false/true. Для числовых сравнений достаточно просто вернуть разницу между двумя числами:

function yearComparator(auto1, auto2) { 
    return auto1.year - auto2.year; 
} 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

+0

Я вижу, что вы имеете в виду, и все работает как шарм. К сожалению, я пытаюсь выполнить некоторые требования к назначению, которые требуют использования функции sortArr и дал мне истинный/ложный компаратор. Похоже, меня заставляют прыгать через дополнительные обручи, чтобы удовлетворить требованиям, которые действительно не оставляют меня с отличным кодом ... но с тех пор, как я начал работу на javascript на прошлой неделе, я не могу сказать, что знаю, что я говорю о – Derkus

+0

В этом случае функция 'sortArr' потенциально должна дважды вызывать« компаратор »и ​​возвращать правильный результат -ve, 0, + ve на основе того, являются ли a> b, b> a или нет (т.е. они равны). Это не затрагивает актуальную проблему, которая связана с тем, как вы пытались передать 'cars.logMe (true)' функции 'forEach'. – Alnitak

+0

Сладкий, у меня все получилось. Спасибо за тонну за вашу помощь.Я упаковал ваш вход в функцию sortArr, переписал их поставляемый компаратор и удалил гигантскую кучу ненужного кода, который только пугал меня дальше. Он работает сейчас и намного красивее. – Derkus

0

Основная проблема заключается в «automobiles.logMe (истина)». Автомобили - это массив автомобильных объектов. Каждый элемент в массивных автомобилях может получить доступ к функции своего прототипа logMe(), но не к самому массиву.

Кроме того, doStuff (массив [i]) отражает то, что вы должны узнать больше о трех важных функциях (вызов, применение, привязка). Немного взглянув на эту статью, вы сможете: http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/

+0

Спасибо за подсказку! Dang right Мне нужно узнать больше об этих функциях. Спасибо за ссылку. – Derkus

+0

Я не согласен с использованием '.call' или' .apply' здесь (и '.bind', безусловно, не имеет значения). Стандартный ES5 'Array.prototype.forEach' не поддерживает установку' this' отдельно на каждой итерации - он полагается на входящий вызов, чтобы сделать это, если это необходимо. Однако он задает общий контекст для любой итерации. – Alnitak

+0

Я закончил тем, что не использовал этот бит кода, но они определенно являются функциями, которые мне нужно узнать больше, поэтому ссылка очень полезна. – Derkus

Смежные вопросы