声明:本文是以题目的形式运用js知识点解决问题来提升对js知识点的理解
格式为 题目;方法;原因;缺点(如果方法有缺点的话);实现代码;
基础篇
1.分支结构
1.判断一个字符串是不是纯数字(字符串中不包含小数即以下方法都不能判断含小数的字符串)
方法一:字符转数字的严格模式+if()的隐式类型转换
原因:严格模式下非数字为NaN,NaN在if()的隐式类型转换中为false
缺点:无法判断全是0的数字(因为if()的隐式类型转换中0为false,但实际上0也是数字)
var str1 = "001";
// 方式一:无法判断全是0的数字
if( Number(str1) ){
alert("是纯数字");
}else{
alert("不是纯数字");
}
方法二:isNaN()+if()的隐式类型转换+if()的隐式类型转换
原因:isNaN()会自动将字符串转换成数值并判断数值是否为NaN
if( isNaN(str1) ){
alert("不是纯数字");
}else{
alert("是纯数字");
}
方法三:算术运算符的隐士类型转换(除+
外)+if()的隐式类型转换
原因:-, *, /, %
会将两边的数据作为数值型数据计算,当-,*,/,%
两边的数据无法转成数字时,会转成NaN,NaN参与任何运算都是非法的
缺点:无法判断全是0的数字(因为if()的隐式类型转换中0为false,但实际上0也是数字)
if( str1 - 0 ){
alert("是纯数字");
}else{
alert("不是纯数字");
}
方法四:字符转数字的非严格模式+if()的隐式类型转换
原因:如果是非纯数字的话,数值在转后会造成数值丢失
if( parseInt(str1) == str1 ){
alert("是纯数字");
}else{
alert("不是纯数字");
}
2.判断一个字符是不是空字符
方法一:if()的隐式类型转换
原因:在if()的隐式类型转换中,字符非空为true
var str2 = " ";
if(str2){
alert("不为空字符");//空格也是字符
}else{
alert("是空字符");
}
方法二:字符串内容为空的情况下根据字符串为空的属性或者是类型
原因:字符串为空,其值为undefined,同时undefined(类型undefined)的值与null(类型object)相等
if(str==null || str==undefined || str===""){
console.log("是空字符");
}else{
console.log("不是空字符");
}
方法三:字符串内容不为空的情况下根据字符串的属性和是字符串的长度
原因:字符串内容不为空其属性为string,长度大于0
if(typeof str == "string" && str.length>0){
console.log("不是空字符");
}else{
console.log("是空字符");
}
3.根据输入的月份和当前天数计算是平年的第几天
方法:switch的case穿透
原因:不加break就会引起case穿透,可以利用case穿透做出累加的效果
<script>
// 月份
var mouth = 12;
// 天数
var day = 31;
// 平年的第多少天
var data = 0;
switch(mouth){
case 12:{
data += 30;
}
case 11:{
data += 31;
}
case 10:{
data += 30;
}
case 9:{
data += 31;
}
case 8:{
data += 31;
}
case 7:{
data += 30;
}
case 6:{
data += 31;
}
case 5:{
data += 30;
}
case 4:{
data += 31;
}
case 3:{
data += 28;
}
case 2:{
data += 31;
}
case 1:{
data += day;
break;
}
default:{
alert("输入月份错误");
break;
}
}
console.log(data);
</script>
2.循环
1.打印以下图案
***
*****
*******
*********
***********
*************
***************
方法:for循环嵌套
原因:第一层for循环控制行,第二层for循环控制列;这个图案分为三个部分,左边是空格,右边是*
号1和*
号2
for(var i=0;i<7;i++){
// 空格部分
for(var j=7;j>i;j--){
document.write(" ");
}
// *号区域1,正常排列,但被空格部分挤往右边,就会看着是往右靠了
for(var j=0;j<=i;j++){
document.write("*");
}
// *号区域2
for(var j=0;j<=i+1;j++){
document.write("*");
}
// 换行
document.write("<br>");
}
2.有一个棋盘,有64个方格,在第一个方格里面放1粒芝麻重量是0.00001kg,第二个里面放2粒,第三个里面放4,第四个里面放8,棋盘上放的所有芝麻的重量
方法:for循环嵌套
原因:第一层for循环控制方格,第二层for循环控制方格里面放的芝麻数量
var sum = 0;
for(var i=0;i<64;i++){
var a = 1;//每当下面的for执行结束,sum加完之后重置a变量
for(var j=0;j<i;j++){
a = a * 2;
}
// console.log(a);
sum += a;
}
console.log(sum * 0.00001);
3.函数
1.编写函数,实现任意个任意数字的和
方法:用arguments接收数据,再通过索引遍历处理
原因:arguments用来保存当前函数的所有的实参(不受形参的数量影响)
var sum=0;
function add(){
for(var i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
console.log(add(1,1,1,1,1));
2.编写一个函数,计算两个数字的和/差/积/商 /余,要求:使用传参的方式
方法:switch分情况处理
原因:因为传入的算术运算符不同要进行的操作也不同,根据传入的算术运算符决定要怎么运算
function compute(n1, n2, sy) {
switch (sy) {
case "+": {
return console.log(n1 + n2);
}
case "-": {
return console.log(n1 - n2);
}
case "*": {
return console.log(n1 * n2);
}
case "/": {
return console.log(n1 / n2);
}
case "%": {
return console.log(n1 % n2);
}
default: {
alert("运算符输入错误");
}
}
}
compute(1, 2, "+");
compute(1, 2, "-");
compute(1, 2, "*");
compute(1, 2, "/");
compute(1, 2, "%");
3.编写一个函数,计算任意两个数字之间所能组成的两位数的奇数,数字必须是个位数。比如: 计算0,3之间能组成的奇数个是01、21、03、13、23、31
方法:循环遍历然后判断
原因:先确定两个数字之间的范围,再用字符串拼接这些范围内的数字,遍历这些数字,符合条件的输出
function compute(n1, n2) {
if(n1>n2){
var temp=0;
temp=n1;
n1=n2;
n2=temp;
}
for (var i = 0; i <= n2; i++) {
for (var j = 0; j <= n2; j++) {
//判断奇偶,不要重复的,这里包含了字符,if()的隐式类型转换
if (("" + i + j) % 2 && i !== j) {
console.log("" + i + j);
}
}
}
}
compute(3, 0);
4.递归
1.计算n的阶乘
方法:递归
原因:阶乘的计算是一个重复的过程,是有规律可寻的,fn(n) = n * fn(n-1)
function fn(n){
if(n === 1){
return 1;
}else{
return n * fn(n-1);
}
}
console.log(fn(10));
2.有一对幼兔,幼兔1个月后长成小兔,小兔1个月后长成成兔并生下一对幼兔,问8个月后有多少对兔子,幼兔、小兔、成兔对数分别是多少?
方法:循环或递归,此处用递归解决总数量
原因:当月成兔和幼兔的数量一样,成兔是上个月的小兔+上个月的成兔,幼兔是上个月的成兔+上个月的小兔,小兔是上个月的幼兔,可以抽象成fn(n) = fn(n-1) + fn(n-2),此时有两个条件fn(1) = 1;fn(2) = 1;
function fn(n){
if(n === 1 || n === 2){
return 1;
}
return fn(n-1) + fn(n-2);
}
console.log(fn(8));
3.编写一个函数,输入n为偶数时,调用函数求1/2+1/4+…+1/n,当输入n为奇数时,调用函数求1+1/3+…+1/n
方法一:递归
原因:先分两种情况,偶数和奇数.偶数:fn(6)=1/6+1/4+1/2可化为fn(n)=1/n+fn(n-2),此时有一个特殊情况即n=2时值为1/2,同理可得奇数
function fn(n) {
if (n === 1) {
return 1;
} else if (n === 2) {
return 1 / 2;
}
// 奇偶运算的都一样,可以用一个式子返回
return 1 / n + fn(n - 2);
}
console.log(fn(4));
方法二:循环
原因:与上述原理相同
function fn(n) {
var sum = 0;
// 奇数
if (n % 2) {
// i的初始值和i += 2 区分奇偶
for (var i = 1; i <= n; i += 2) {
sum = sum + 1 / i;
}
} else {
for (var i = 2; i <= n; i <