我正在编写一个程序,根据此代码中列出的标准识别特殊数字wata kata:
http://www.codewars.com/kata/catching-car-mileage-numbers
以下是我的完整代码和测试的链接:
我有单元测试我的功能,测试每个特殊数字条件,它们似乎按预期工作。但是,我有一个功能:
function allTests(number, awesomePhrases){
var num = number.toString().split('');
// if any criteria is met and the number is >99 return true
return number > 99 && (allZeros(num) || sameDigits(num) || incrementing(num) || decrementing(num) || palindrome(number) || matchPhrase(number, awesomePhrases)) ? true : false;
}
确定是否满足任何特殊号码的标准,并且不能按预期工作。例如,当我在7000上测试allZeros()函数时,它返回true,但alltests(7000)返回false。是否有关于我不理解的逻辑表达式链如何评估或者其他问题是什么?
我看过W3schools和MDN试图诊断问题。
答案 0 :(得分:0)
将你所有的!==改为!=将会改变。
答案 1 :(得分:0)
只要 allTests()使用第二个参数执行,即使它是空字符串,也会出现错误结果,如下所示:
allTests(7000,"");
如果仅使用一个参数(即数字)调用该函数,则会出现此错误:
未捕获的TypeError:无法读取未定义的属性“长度”
错误消息指的是逻辑链中的一个函数,即 matchPhrase(),它需要两个参数:数字和 awesomePhrases 。如果不是提供空字符串,而是使用null,那么您也会得到相同的错误消息。
JavaScript不支持默认参数的概念 - 至少不是以人们可能期望的方式;参数默认为undefined。但是有一种方法可以解决这个障碍并改进代码,以便可以避免这种不必要的错误。只需更改 matchPhrase(),如下所示:
function matchPhrase(number, awesomePhrases){
awesomePhrases = typeof awesomePhrases !== 'undefined' ? awesomePhrases : "";
for(var i = 0, max=awesomePhrases.length; i < max; i++){
if(number == awesomePhrases[i]){
return true;
}
}
return false;
}
第一个语句接受第二个参数的值,只要它不是未定义的值;如果是,则将变量设置为空字符串。 (技术来源:here)。
为了使代码更易于理解,我建议按如下方式重写allTests(),以便代码遵循更明确的自我文档样式:
function allTests(number, awesomePhrases){
var arrDigits = number.toString().split('');
// if any criteria is met and the number is >99 return true
return number > 99 && (allZeros( arrDigits ) || sameDigits( arrDigits ) || incrementing( arrDigits ) || decrementing( arrDigits) || palindrome(number) || matchPhrase(number, awesomePhrases)) ? true : false;
}
此函数接受一个数字并使用其toString()方法将数字转换为字符串。生成的字符串不可见将在空字符串上分割,因此arrDigits的结果是一个数字字符串数组,每个字符串只包含一个数字。这是随后出现的allZeros()问题的起源点,它将字符串数字与数字进行比较。
顺便说一句,在函数allTests()中有一个非常冗长的三元表达式。语法很好,但您可能希望按如下方式重写代码:
function getCriteriaStatus(arrDigits,number,awesomePhrases) {
var criteria = new Array();
criteria[0] = allZeros( arrDigits );
criteria[1] = sameDigits( arrDigits );
criteria[2] = incrementing( arrDigits );
criteria[3] = decrementing( arrDigits);
criteria[4] = palindrome(number);
criteria[5] = matchPhrase(number, awesomePhrases);
var retval = false;
for (var i=0, max=6; i < max; i++) {
if ( criteria[i] == true ) {
retval = true;
break;
}
}
return retval;
}
function allTests(number, awesomePhrases){
var arrDigits = number.toString().split('');
var criteria_met = getCriteriaStatus(arrDigits,number,awesomePhrases);
return (number > 99 && criteria_met);
}
为了在调用allZeros()时从allTests()获得所需的真实结果,而不是使用parseInt()使代码复杂化,我建议重写allZeros()和包含代码的任何其他函数通过从标识运算符更改为相等运算符,将数字字符串值与数字进行比较。此更改仅涉及将===
替换为==
以及将!==
替换为!=
。使用标识运算符比较相同数据类型的值的代码,这些运算符可能并且可能应该保持不变。 (见here)。