我正在使用 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>
谢谢!
附注如果您对构建应用程序有任何想法,欢迎提出所有想法;我特别担心最后在就绪函数中依次调用所有函数的方式。由于某种原因,这看起来有点困惑。
最佳答案
你的问题出在这里:
$(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>
关于javascript - 无法在状态修改方法中访问状态对象的对象属性(TypeError),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41609611/