【问题标题】:Unable to access object property of state object in state modification method (TypeError)无法在状态修改方法中访问状态对象的对象属性(TypeError)
【发布时间】:2017-01-12 09:37:46
【问题描述】:

我正在使用 jQuery 开发一个文本分析器,它返回字数、唯一字数、平均字长和平均句子长度。

在我意识到我的结构很糟糕之前,我已经让它工作了(至少到了一半,直到唯一的字数统计功能)。所以我重构了它……现在我根本无法让它工作。

在第 65 行,我收到了 TypeError: Cannot read property 'length' of null。这是对state.sentences 的引用,当我使用console.log 时,我得到null。我刚刚注意到,当我输入一个完整的句子作为输入时,它不会出现(并且它会正确记录句子),但它仍然没有将内容呈现到 DOM。

我在这里做错了什么?很明显,我尝试访问 state 对象的方式有所不同——但究竟是什么,我无法理解。

这里是 index.js:

'use strict'

// state object

var state = {
    text: "",
    words: [],
    uniqueWords: [],
    sentences: [],
    wordLengths: [],
    sentenceLengths: [],
    wordCount: 0,
    uniqueWordCount: 0,
    averageWordLength: 0,
    averageSentenceLength: 0
}


//state modification functions

var getText = function(state) {
    state.text = $('#user-text').val()
}

var getWords = function(state) {
    state.words = state.text.match(/[^_\W]+/g)
    //need to also change all uppercase to lowercase
}

var getSentences = function(state) {
    state.sentences = state.text.match( /[^\.!\?]+[\.!\?]+/g )
}

var getUniqueWords = function(state) {
    for (var i = 0; i < state.words.length; i++) {
        if (state.uniqueWords.indexOf(state.words[i]) < 0) {
            state.uniqueWords.push(state.words[i])
        }
    }
}

var getWordCount = function(state) {
    state.wordCount = state.words.length
}

var getUniqueWordCount = function(state) {
    state.uniqueWordCount = state.uniqueWords.length
}

var getWordLengths = function(state) {
    for (var i = 0; i < state.words.length; i++) {
       state.wordLengths.push(state.words[i].length)
       console.log(state.wordLengths)
    }
}

var getAverageWordLength = function(state) { 
    var sum = state.wordLengths.reduce(function(a, b) {
        return a + b
    }, 0)
    state.averageWordLength = sum/state.wordLengths.length
}

var getSentenceLengths = function(state) {
    for (var i = 0; i < state.sentences.length; i++) {
        state.sentenceLengths.push(state.sentences[i].length)
    }
}

var getAverageSentenceLength = function(state) {
    var sum = state.sentenceLengths.reduce(function(a,b) {
       return a + b
    }, 0)
   state.averageSentenceLength = sum/state.sentenceLengths.length
}

// render functions

var renderWordCount = function(state, element) {
    $("dl").toggleClass('hidden')
    return element.append(state.wordCount)
}

var renderUniqueWordCount = function(state, element) {
    $("dl").toggleClass('hidden')
    return element.append(state.uniqueWordCount)
}

var renderAverageWordLength = function(state, element) {
    $("dl").toggleClass('hidden')
    return element.append(state.averageWordLength)
}

var renderAverageSentenceLength = function(state, element) {
    $("dl").toggleClass('hidden')
    return element.append(state.averageSentenceLength)
}

// event listener functions

$(function() {
    $('button').click(function() {
        event.preventDefault()
        getText(state)
        getWords(state)
        getSentences(state)
        getUniqueWords(state)
        getWordCount(state)
        getUniqueWordCount(state)
        getAverageWordLength(state)
        getSentenceLengths(state)
        getAverageSentenceLength(state)
        renderWordCount(state, $('.wordCount'))
        renderUniqueWordCount(state, $('.uniqueWordCount'))
        renderAverageWordLength(state, $('.averageWordLength'))
        renderAverageSentenceLength(state, $('.averageSentenceLength'))
    })
})

这里是 index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Text analyzer</title>
    <meta charset="utf-8">

    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css">
    <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
    <div class="container">
        <main>
            <h1>Text analzyer</h1>
            <p>Paste in text below, submit, and get some basic stats back.</p>
            <form class="js-form">
                <div>
                    <label for="user-text">Text to analyze</label>
                    <textarea cols="60" rows="20" id="user-text" name="user-text" placeholder="What have you got to say?" required></textarea>
                </div>
                <div>
                    <button type="submit">Analyze it!</button>
                </div>
            </form>

            <dl class="hidden text-report">
                <dt>Word count</dt>
                <dd class="wordCount"></dd>

                <dt>Unique word count</dt>
                <dd class="uniqueWordCount"></dd>

                <dt>Average word length</dt>
                <dd class="averageWordLength"></dd>

                <dt>Average sentence length</dt>
                <dd class="averageSentenceLength"></dd>
            </dl>
        </main>
    </div>
    <script src="jquery-3.1.1.js"></script>
<!-- <script src="app.js"></script> -->
    <script src="index.js"></script>
</body>
</html>

谢谢!

附:如果您对构建应用程序有任何想法,欢迎提出所有想法;我特别担心我在最后的就绪函数中一个接一个地调用所有函数的方式。由于某种原因,这似乎有点混乱。

【问题讨论】:

  • 关于构建您的应用程序,显示原型模式可能是您的一个不错的选择,更多讲座在weblogs.asp.net/dwahlin/…
  • 谢谢!这看起来很有用...我会尽快阅读。

标签: javascript jquery object properties


【解决方案1】:

你的问题出在这里:

$(function() {
    $('button').click(function() {
        event.preventDefault()
        getText(state) // <---at this point you are passing an object to set the text in.
        // state object but getText has some-thing which is not correct
        //.....other too
    })
})

var getText = function(state) {
    state.text = $('user-text').val() // <-----Here `user-text` is not a valid
    // html element and jquery doesn't recognize it.
    // So, You should change it to a valid css selector.
}

所以,最终你应该使用 Id 选择器:

$('#user-text').val() 

由于您的 html 元素具有 Id 属性:

<textarea cols="60" rows="20" 
          id="user-text" 
          name="user-text" 
          placeholder="What have you got to say?" required></textarea>

【讨论】:

  • 谢谢!编辑以反映这一点。
猜你喜欢
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多