Неверное исключение в JavaScript. Вызов TypeError не является функцией [duplicate]

1

Я играл с методом вызова в JavaScript, и я нашел что-то интересное:

Я создавал пользовательскую функцию карты, и я сделал что-то вроде этого:

function map(collection, callback, context) {
    if (!collection || !collection.hasOwnProperty('length') || typeof(callback) !== 'function') {
        throw new TypeError();
    }

    var newArray = [];
    var isFunction = typeof(callback.call) === 'function'; // this I added after to prove my point.
    console.log('is callback.call a function? ' + (isFunction ? 'yes it is!' : 'no, it is not a function'));
    for (var i = 0, len = collection.length; i < len; i++) {
        newArray[i] = callback.call(context, collection[i], i, collection);
    }

    return newArray;
}

В этот момент я выполнил свою функцию map со следующими аргументами:

var arr = map(Array.apply(null, { length: 2 }), Number.call);

Я пропустил значение для аргумента context, поэтому он не undefined. Что должно быть круто. Также, что немного странно, как callback я передал метод call поэтому в конце: я call метод call методу call (что тоже круто).

Но по неизвестной причине браузер дает мне эту ошибку:

is callback.call a function? yes it is!
Uncaught TypeError: callback.call is not a function
    at map (eval at map (:10:9), <anonymous>:10:32)
    at eval (eval at map (:10:9), <anonymous>:15:11)
    at map (<anonymous>:10:9)
    at <anonymous>:1:1

Интересно, что является реальной причиной этого. callback.call - это функция. Есть ли способ справиться с таким делом? Как я могу проверить, предоставили ли аргументы мне такую ошибку?

Именно тогда я предоставляю контекст:

map(Array.apply(null, { length: 2 }), Number.call, Number)
// is callback.call a function? yes it is!
// [0, 1]

CodePen (отсутствует ошибка в консоли, я рекомендую использовать браузер для воспроизведения)

EDIT: просто для уточнения контекста не требуется вообще:

map([1, 2], function(i) {
    return i + 5;
});
// is callback.call a function? yes it is!
// [6, 7]

EDIT # 2 Я вижу, как другие вопросы относятся к моей. И они объяснили причину этого, также в Firefox есть неплохое сообщение об ошибке для этого:

TypeError: Function.prototype.call called on incompatible undefined

Поэтому мой последний вопрос:

Есть ли способ обнаружить такую "несовместимость"?

Теги:
error-handling

1 ответ

1
Лучший ответ

Вы Number.call функцию Number.call в качестве параметра. Таким образом, внутри вашей функции callback функции map уже Number.call функция Number.call. Тогда вы больше не должны использовать callback.call. Просто использовать callback должно быть исправление.

Это всего лишь моя идея с 2 центрами. Надеюсь, поможет!

EDIT: Потому что call является функцией Function.prototype поэтому он будет отображаться в каждом экземпляре функции. И this контекст должен быть функцией. Момент, вы передаете Number.call на свою новую map, вы уже потеряли свой контекст, потому что внутри новой map this уже не функция.

  • 0
    Дело в том, что callback.call - это функция, даже мысль кажется неуместной. У меня вопрос, возможно ли это обнаружить? И какого чёрта я получаю такую ошибку?
  • 0
    Потому что call является функцией Function.prototype поэтому он будет появляться в каждом экземпляре функции.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню