2016-09-14 4 views
0

По какой-то причине я не могу получить длину массива (он неопределен, если он незаселен, не так ли?).Является ли .length подходящим вызовом массива JavaScript?

define(function() { 
    'use strict'; 

    var self = {}, 
    events = {}; 

    self.publish = function publish(eventName, data) { 
    var subscribers, x, length; 

    if (events[eventName]) { 
     return false; 
    } 

    subscribers = events[eventName]; 

    for (x = 0, length = subscribers.length || 0; x < length; x += 1) { 
     subscribers[x](data); 
    } 

    return true; 
    }; 

    self.subscribe = function subscribe(eventName, func) { 
    if (!events[eventName]) { 
     events[eventName] = []; 
    } 

    events[eventName].push(func); 
    }; 
    return self; 
}); 

JSLint говорит: «Ожидаемый»; и вместо этого увидел «,». Жасмин говорит: «ТипError: Невозможно прочитать свойство« длина »неопределенного»

Почему длина не установлена ​​на 0? Я неправильно понял синтаксис здесь?

+0

Не следует изменять '' 'for (x = 0, subscription.length || 0; x

+0

Почему вы считаете, что' подписчики 'являются массивом? Кажется, он «неопределен». – user2357112

+0

'undefined, если он незаселен, правый' нет, он равен нулю. Имеет смысл - в массиве есть нулевые объекты, поэтому длина равна нулю. – vlaz

ответ

0

Я думаю, что проблема с этой линии:

for (x = 0, subscribers.length || 0; x < length; x += 1) { 

вы определили переменную «длину», но никогда не инициализированы/назначенные на него данные.

Подробно:

subscribers.length || 0 

Что это должен делать?

x < length 

x < length or x < subscribers.length? 
+0

Я забыл добавить задание. Ответ по-прежнему «длина не определена» –

+0

@KenIngram, как вы его модифицировали? Вы уверены, что 'events [eventName]' содержит массив? –

-1

как Дон Bhrayan Сингх сказал

ваш код должен быть

for (var x = 0, length = subscribers.length || 0; x < length; x += 1) { 
    subscribers[x](data); 
} 

ваш предыдущий код будет работать, как этот

// x = 0,   0   ; x < undefined; x += 1 
for (x = 0, subscribers.length || 0; x < length; x += 1)  { 
    subscribers[x](data); 
} 
+0

'x = 0, True; x vlaz

+0

Вы правы, чтобы сказать, что выражение будет оцениваться равным 0. но как его можно присвоить x? Я думал, что js просто оценит выражение. – vdj4y

3

Вы пропускаете отрицанием в функции publish :

self.publish = function publish(eventName, data) { 
    var subscribers, x, length; 

    if (events[eventName]) { // <= Here you exit if there are subscribers, and continue if there arent 
     return false; 
    } 

    subscribers = events[eventName]; // So subscribers is guaranteed to be undefined 

    // can't get length (or any property) of undefined 
    for (x = 0, length = subscribers.length || 0; x < length; x += 1) { 
... 

Это приводит к сбою ваших тестов. Это путь:

self.publish = function publish(eventName, data) { 
    // you can use const and let 
    // you are storing subscribers in a variable anyway, so why not doing it 
    // before the check? 
    const subscribers = events[eventName]; 

    if (!subscribers) { 
     return false; 
    } 

    // you don't need to cache length in a variable, iirc it only improves performance slightly on IE browsers 
    // neither need you `|| 0` 
    // there other ways iterating through an array, see for..of and Array.prototype.forEach 
    for (let x = 0; x < subscribers.length; x++) { 
     subscribers[x](data); 
    } 

    return true; 
}; 

it is undefined if it's unpopulated, right?

Нет, длина массива равна нулю, если его пустым. Вы получаете неопределенное значение при чтении отсутствующего свойства объекта, но длина массива всегда является числом.

+0

Спасибо. Это немного смутило. –

0

Как оказалось, код работал нормально, когда я исправил опечатку.

if (events[eventName]) { 

должен быть

if (!events[eventName]) { 

Все работало как задумано после этой коррекции. Мои проблемы с отладкой всегда что-то глупо второстепенное

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