[英]Unable to access object property of state object in state modification method (TypeError)
我正在研究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>
谢谢!
PS如果您对构建应用程序有任何想法,欢迎所有想法; 我特别关注我在最后的ready函数中一个接一个地调用所有函数的方式。 出于某种原因,这似乎有点混乱。
你的问题在于:
$(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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.