Javascript charAt不是一个函数

Javascript charAt不是一个函数,javascript,Javascript,我试图在createArrayMap()函数中创建一个键映射来跟踪字符串中每个字符的频率,但我一直从firebug中得到这个错误:TypeError:str.charAt(…)不是一个函数 我在Mozilla的开发者网站上找到了charAt()函数,它应该是一个存在的函数 var input; var container; var str; var arrMapKey = []; var arrMapValue = []; function initDocElements() {

我试图在createArrayMap()函数中创建一个键映射来跟踪字符串中每个字符的频率,但我一直从firebug中得到这个错误:
TypeError:str.charAt(…)不是一个函数

我在Mozilla的开发者网站上找到了charAt()函数,它应该是一个存在的函数

var input;
var container;
var str;
var arrMapKey = [];
var arrMapValue = [];


function initDocElements() {

    container = document.getElementById("container");
    input = document.getElementById("inputbox");

}

function createArrayMap() {
    str = input.value;
    for (var i = 0; i < str.length; i++) {
        if (arrMapKey.find(str.charAt(i)) == undefined) {
            arrMapKey.push(str.charAt(i));
            arrMapValue.push(1);
        }
    }
}

function keyPressHandler() {
    createArrayMap();
    console.log(arrMapKey);
    console.log(arrMapValue);
}

function prepareEventHandlers() {
    input.onfocus = function() {
        if (this.value == "Start typing here!") {
            this.value = "";
        }
    };
    input.onblur = function() {
        if (this.value == "") {
            this.value = "Start typing here!";
        }
    };
    input.onkeyup = keyPressHandler;
}

window.onload = function() {
    initDocElements();
    prepareEventHandlers();
};
var输入;
var容器;
var-str;
var arrMapKey=[];
var arrMapValue=[];
函数initDocElements(){
容器=document.getElementById(“容器”);
输入=document.getElementById(“inputbox”);
}
函数createArrayMap(){
str=输入值;
对于(变量i=0;i
你没有以最有效的方式做事。。。如果你把它改成这样,每次按键都会不断更新,那会怎么样

var keyMap = {};
...
input.onkeyup = keyPressHandler;

function keyPressHandler(e) {
  var char = String.fromCharCode(e.keyCode);
  if(!(char in keyMap))
    keyMap[char] = 1;
  else
    keyMap[char]++;
}
问题不在于,而在于

find
的第一个参数是回调,但是
str.charAt(i)
的结果是一个字符,而不是回调函数

要搜索数组中的元素,可以使用注释中已经建议的as@adeneo

函数createArrayMap(){
var str=input.value;
对于(变量i=0;i

请参见

这已经得到了回答,但这是我对您的问题的看法(除了阵列解决方案之外,还有一个对象选项)

我移动了一些变量,这样可以减少全局变量,添加注释,并使用输出进行模拟,以便在页面上而不是控制台上显示

除了
Array.find()
问题之外,您没有在构建方法上初始化数组,因此,您可能以错误的字母计数结束

HTML:


输出将显示在此处

JS:

var输入,//全局变量
集装箱//
产出//
/**
*初始化组件
*/
函数initDocElements(){
容器=document.getElementById(“容器”);
输入=document.getElementById(“inputbox”);
输出=document.getElementById(“输出”);
}
/**
*创建字母频率数组。
*请注意,每次单击一个字母,都是从头开始的。
*好的一面:不需要处理“退格”
*坏的一面:效率。我没有试着用大量的文字来表达,但你明白了。。。
*/
函数createArrayMap(){
var索引,//明显
tempChar,//temp vars for:char
tempStr=input.value,//字符串
len=tempStr.length,//用于循环迭代
arrMapKey=[],//我们的密钥
arrMapValue=[];//我们的值
对于(var i=0;i-1){
arrMapValue[索引]+;
}   
//否则,按键数组,按1键数组
否则{
arrMapKey.push(tempChar);
arrMapValue.push(1);
}
}
//一些临时输出添加到
//文本区域下方的段落。
output.innerHTML=“数组键:”+arrMapKey.toString()+
“
数组值:”+arrMapValue.toString(); } 函数keyPressHandler(){ createArrayMap(); } 函数prepareEventHandlers(){ input.onfocus=函数(){ if(this.value==“在此处开始键入!”){ 此值为“”; } }; input.onblur=函数(){ 如果(this.value==“”){ this.value=“在此处开始键入!”; } }; input.onkeyup=keyPressHandler; } window.onload=函数(){ initDocElements(); 准备好所有文件(); };
顺便说一句,正如评论所建议的那样,对对象执行此操作会更好、更短,因为您关心的是对象是否具有当前字符作为属性:

/**
 * Same as above method, using an object, instead of 2 arrays
 */
function createObject() {
    var index,                  // obvious
        tempChar,               // temp vars for: char 
        tempStr = input.value,  // string
        len = tempStr.length,   // for loop iteration
        freqObj = {};           // our frequency object

    for (var i = 0 ; i <len ; i++) {
        tempChar = tempStr.charAt(i);   // temp char value

        if (freqObj.hasOwnProperty(tempChar))
            freqObj[tempChar]++;
        else
            freqObj[tempChar] = 1;
    }
}
/**
*与上述方法相同,使用一个对象,而不是两个数组
*/
函数createObject(){
var索引,//明显
tempChar,//temp vars for:char
tempStr=input.value,//字符串
len=tempStr.length,//用于循环迭代
freqObj={};//我们的频率对象

对于(var i=0;我可以让你共享一个指向有此问题的小提琴的链接吗?为什么不直接使用一个对象?
{a:1,b:2,…}
我看不出有任何理由在JavaScript中使用
charAt
“abc”[0]
“abc.charAt”(0)
(因为字符串是一个数组,你可以这样做。)@Derek朕會功夫 - 因为
charAt()
比使用括号符号访问字符串有更好的支持,并且在所有浏览器中都受支持,当然,它必须是一个字符串才能工作。我实际上很好奇
数组.find
方法在做什么,以及在哪里找到它(您确定它不应该是indexOf)?这是一个更简单、更有效的算法。
typeof(keyMap[char])!=“undefined”
可以是
!(char in keyMap)
。否则,+1,这是正确的答案。谢谢!使用对象更好。我没意识到你可以检查属性
var input,      // Global variables
    container,  //
    output;     //

/**
 * Initialize components
 */
function initDocElements() {
    container = document.getElementById("container");
    input = document.getElementById("inputbox");
    output = document.getElementById("output");
}

/**
 * Creates the letters frequency arrays.
 * Note that every time you click a letter, this is done from scratch.
 * Good side: no need to deal with "backspace"
 * Bad side: efficiency. Didn't try this with huge texts, but you get the point ...
 */
function createArrayMap() {
    var index,                  // obvious
        tempChar,               // temp vars for: char 
        tempStr = input.value,  // string
        len = tempStr.length,   // for loop iteration
        arrMapKey   = [],       // our keys
        arrMapValue = [];       // our values

    for (var i = 0 ; i <len ; i++) {

        // These 2 change each iteration
        tempChar = tempStr.charAt(i);
        index = arrMapKey.indexOf(tempChar); 

        // If key exists, increment value
        if ( index > -1) {          
            arrMapValue[index]++;
        }   
        // Otherwise, push to keys array, and push 1 to value array
        else {                      
            arrMapKey.push(tempChar);
            arrMapValue.push(1);
        }
    }

    // Some temp output added, instead of cluttering the console, to the 
    // a paragraph beneath the text area.
    output.innerHTML = "array keys:   "+arrMapKey.toString() + 
        "<br/>array values:"+arrMapValue.toString();
}

function keyPressHandler() {
    createArrayMap();

}

function prepareEventHandlers() {
    input.onfocus = function() {
        if (this.value == "Start typing here!") {
            this.value = "";
        }
    };
    input.onblur = function() {
        if (this.value === "") {
            this.value = "Start typing here!";
        }
    };
    input.onkeyup = keyPressHandler;
}

window.onload = function() {
    initDocElements();
    prepareEventHandlers();
};
/**
 * Same as above method, using an object, instead of 2 arrays
 */
function createObject() {
    var index,                  // obvious
        tempChar,               // temp vars for: char 
        tempStr = input.value,  // string
        len = tempStr.length,   // for loop iteration
        freqObj = {};           // our frequency object

    for (var i = 0 ; i <len ; i++) {
        tempChar = tempStr.charAt(i);   // temp char value

        if (freqObj.hasOwnProperty(tempChar))
            freqObj[tempChar]++;
        else
            freqObj[tempChar] = 1;
    }
}