2015-06-25 63 views
1
  1. 我正在學習基於JavaScript的JavaScript,並且在其中一個章節中,遇到了這個錯誤。不知道我在這裏做錯了什麼。我得到一個錯誤「無法讀取屬性」indexOf'未定義「的代碼return journal.events.indexOf(event) != -1Eloquent Javascript:Uncaught TypeError:無法讀取屬性'indexOf'的undefined

  2. 此外,有人可以解釋該線路的工作原理嗎?是不是IndexOf應該返回指定值出現的第一個位置(在這種情況下是事件)?但是我在書中看到return journal.events.indexOf(event) != -1;這一行返回true或false。

    var journal = []; 
    
    function addEntry(events, didITurnIntoASquirrel) { 
        journal.push({ 
         events: events, 
         squirrel: didITurnIntoASquirrel 
        }); 
    } 
    
    addEntry(["work", "touched tree", "pizza", "running", 
          "television"], false); 
    addEntry(["work", "ice cream", "cauliflower", "lasagna", 
          "touched tree", "brushed teeth"], false); 
    addEntry(["weekend", "cycling", "break", "peanuts", 
          "beer"], true); 
    
    function hasEvent(event, entry) { 
        return entry.events.indexOf(event) != -1; 
    } 
    
    console.log(hasEvent("pizza", journal)); 
    
+1

你推含*'events'對象*但是沒有' '日誌'上的事件屬性。 –

回答

3

在示例代碼journal是一個數組

var journal = []; <--- Array 

因此events應與指數等訪問:

journal[0].events.indexOf(event) 

     ^
     | 
     | 

在這裏,您需要找 右手食指,讓您的活動

+0

謝謝!得到它了! – paranoidhb

0

要回答你的第二個問題:

「是不是應該的IndexOf返回指定值的出現的第一位置」

是的,indexOf回報-1如果值爲而不是在數組中找到。

因此,如果事件找到了,那麼表達式indexOf(event) != -1將評估爲true

2

我不確定你學習javascript有多遠,所以請原諒我,如果這聽起來有些居高臨下或明顯。

讓我們一次一步地解決這個問題。你從一個空數組開始。

var journal = []; 
console.log(journal); //[] 
//it's defined. It's an empty Array. 

通過調用數組上的push,可以在數組的末尾添加一些內容。 More on Array.push

我不喜歡這個初學者的例子,因爲它期望你已經知道你可以在你將它作爲參數傳遞的時候定義一個對象。這是通過這種方式完成的,因爲您並不真的需要對僅使用一次的對象的變量引用,因此是減少代碼膨脹的好方法。但是在教某人時,詳細程度要好得多。

//Wait, what am I pushing into the journal array? 
journal.push({ 
    events: events, 
    squirrel: didITurnIntoASquirrel 
}); 

這應該更有意義: 先創建一個對象。然後將該對象添加到「日記」數組中。 function addEntry(events,didITurnIntoASquirrel)var temporaryObject = { events:events, squirrel:didITurnIntoASquirrel };期刊。推(temporaryObject); }

現在journal是一個數組,其第一個索引處有一個未命名的對象。

1. console.log(journal); // [temporaryObject] 
    2. console.log(journal[0]); - //temporaryObject 

可見性差異是缺乏parens,但差別很重要。 在第一行你有數組本身,在第二行你有它的內部(即對象)。您需要先獲取對象(通過第2行的技術),然後才能訪問該對象的屬性,如「事件」或「松鼠」。繼續。

addEntry(["work", "touched tree", "pizza", "running", "television"], false); 

接下來,我們調用addEntry函數。這裏同樣困惑。我稍微重寫了一下,以使這些論點更容易理解。

var entry = ["work", "touched tree", "pizza", "running", "television"]; 
addEntry(entry, false); 
//repeat 2 more times with different data 

所以首先我們定義一個數組,然後將它傳遞給addEntry函數。當addEntry函數運行時(它會在我們調用它時運行),「entry」參數將作爲「events」參數表示(簡單的方式:事件 = entry和didITurnIntoASquirrel = false)。 some notes on parameters vs arguments

所以你現在應該能夠理解你正在向addEntry函數傳遞一個數組和布爾值。該函數根據通過參數引用它們的值創建一個對象。該對象然後被添加到日誌數組中。

你最終得到的是4層深度。您有一個名爲journal的數組,其中包含對象。這些對象有一個叫做events的屬性,這是一個不同的數組。該數組中有幾個字符串。要訪問events數組並使用indexOf來查看它是否包含給定的字符串,則需要一次遍歷該深度一個級別。

//journal is the array, journal[0] is the object, journal[0].events is the property of that object 
console.log(journal[0].events) //["work", "touched tree", "pizza", "running", "television"]. 

請注意,這與我們最初放入條目變量中的數據相同。這看起來似乎不必要的複雜,但當我說這種類型的結構在現實生活中很有用時,需要管理面向對象編程中的「事物」之間的數據層次結構或其他邏輯關係時,請相信我。

現在,我們迄今爲止所做的所有工作都是添加到日誌數組中。我們現在需要一個函數來查看它裏面的內容。爲什麼一個功能?所以你不必一遍又一遍地重寫相同的代碼。

function hasEvent(event, journal) { 
    return journal.events.indexOf(event) != -1; 
} 

現在我希望你能看到這個函數中的錯誤。 journal.events不起作用,因爲journal是一個數組,而不是一個對象(你跳過了一個關卡,而你的計算機不夠聰明,無法知道你的意思)journal [0] .events會起作用,因爲你告訴javascript(「來自日誌數組,我想要第一個槽中的對象以及該對象的events屬性」)。

最簡單的解決方法是將journal [0]發送到hasEvent函數而不是日誌。當心,這隻會檢查期刊的第一個索引。實際上,你會想要在hasEvent函數中使用for循環,或者調用該函數來檢查所有索引。現在我們將對它們進行硬編碼,因爲我們知道有3個,但它在現實生活中並不是一個好主意,因爲後來可能會有3個以上的條目)。

這個函數返回調用indexOf()(某個數字或-1)與-1的結果。讓我們再次重寫它,使它更有意義。

新hasEvent功能:

//I renamed the variable so it makes more sense what it really is. It's the object, not the journal array. 
function hasEvent(event, journalEntry) { 
    var index = journalEntry.events.indexOf(event); 
    var result = (index != -1); //true if it was found, false if it wasn't found. 
    return result; //a boolean based on the above comparison. 
} 

//Ack! My kingdom for a "for loop". Don't worry about that right now. 
console.log(hasEvent("pizza", journal[0])); 
console.log(hasEvent("pizza", journal[1])); 
console.log(hasEvent("pizza", journal[2])); 

TL; DR 這裏是工作代碼小提琴: http://jsfiddle.net/o8dg1ts6/1/

+1

在我出現之前,沒有人喜歡這個嗎?男人,這是一個很棒的解釋。代碼在他的例子中編寫的方式不是很明顯,它似乎缺少幾個步驟。本課並不是我最喜歡的,但如果你正在寫它,我想我會更喜歡它!謝謝你的信息,太糟糕了,OP沒有看到它的價值。 – Trapp

相關問題