char不是一个功能

时间:2014-01-18 23:47:31

标签: javascript

我正在尝试创建一个键映射,用于跟踪createArrayMap()函数中字符串的每个字符的频率,但我不断从firebug中获取此错误:TypeError: str.charAt(...) is not a function

我在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();
};

3 个答案:

答案 0 :(得分:4)

问题不在于String.charAt(),而在于Array.find()

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

要搜索数组中的元素,可以使用Array.indexOf()作为评论中已建议的@adeneo

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

请参阅JSFiddle

答案 1 :(得分:0)

你不会以最有效的方式处理事情......如果你把它改成这样,那么你会不断更新每个按键怎么办?

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

function keyPressHandler(e) {
  var char = String.fromCharCode(e.keyCode);
  if(!(char in keyMap))
    keyMap[char] = 1;
  else
    keyMap[char]++;
}

答案 2 :(得分:0)

这已经回答了,但这是我的问题版本JSBIN LINK(除了数组解决方案之外还有一个对象选项)。

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

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

HTML:

<div id="container">
<textArea id="inputbox"></textArea></div>
<p id="output">output will show here</p>

JS:

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();
};
BTW,正如评论所暗示的那样,使用对象执行此操作会更好更短,因为您只关心对象是否将当前char作为属性:

/**
 * 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;
    }
}