2016-09-14 13 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は、「期待している」、代わりに鋸 '、'。 Jasmineは "TypeError:プロパティ '長さ'が未定義です。 '

なぜ長さは0に設定されていませんか?私はここでの操作の構文を誤解していますか?

+0

(x = 0、subscribers.length || 0; x

+0

なぜあなたは' subscribers'が配列であると思いますか?それは '未定義 'と思われます。 – user2357112

+0

'未使用の場合は未定義です。いいえ、ゼロで​​す。意味があります - 配列内にオブジェクトがないため、長さはゼロです。 – 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シンが

あなたのコードは、あなたの前のコードは、あなたがpublish機能に否定を欠けているこの

// 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 <未定義; x + = 1'そこに「真」とは何ですか? 'subscribers.length ||の結果、それは何でも完全に間違っています。 0 'は常に現在の長さに等しい(長さが「0」の場合はORで進み、依然として「0」を返す)。しかし、コンマ演算子が存在するので、その式は 'x'に割り当てられます。 _実際に何が起きるかは 'x = subscribers.length; x <未定義; x + = 1'であり、チェックは常に 'false'になります。なぜなら、' undefined'は決して任意の数を超えることはないからです。 – vlaz

+0

あなたは式が0と評価されると言うのは正しいですが、xにどのように代入することができますか?私はjsが単に表現を評価すると思った。 – vdj4y

3

のように実行します

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

する必要があります言ったように:

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]) { 

ことになっています。 私のデバッグの問題は常に馬鹿げたものです。

関連する問題