第二周笔记

224 阅读17分钟

第二周笔记整理

day6

一:数据类型转换

1、强制转换

1):转字符串:2a: xx.to String   ——>undefined和null不能用
b: String(xx);    ——>万能,不能用

2):转数字 3a: parseInt(str/num);  ——>专门用于将数字字符串转为整数
b: parseFloat(str);   ——>专门用于将字符串转为浮点数(小数)
c: Number(xx);   ——>万能,不用

3):转布尔值
a: Boolean(x);   ——>万能,不用
b: 哪些东西转为false60,“ ”,undefined,Null,NaN,false   其余全为trueif(Boolean(条件)){
                            };
     while(Boolean(循环条件)){
                            };
     

2、隐式转换:都出现在运算符种

二:运算符和表达式

1、算术运算:+ - * / %

  前面四个运算符和小时候一样

但是特殊:

a、%:取余,俗称模,两个数相除,但是不取商,而是取除不尽的余数

		5%2 ==> 1
		作用:
		  1、*判断奇偶性
			num%2;//结果为0说明是一个偶数,结果为1说明是一个奇数
		  2、获取某个数字的最后n位
			1234%10;//4
			1234%100;//34
			1234%1000;//234
			

b、自带隐式转换:悄悄地转换,数据类型会发生变化,我们程序员看不见

常理来说只有数字才能参与算术运算,但是其实字符串也可以,一定要切记下面的几句话
*****默认运算符左右两边都会悄悄转换为一个数字,再运算
特殊:
a、+运算,只要碰上一个字符串,则都会变为字符串,+运算也不再是+运算,变成了拼接操                
b、-*/%运算:有字符串也可以转为数字,但是必须是纯数字组成的字符串才可以,只有包含一个非数字字符,结果则为NaN
NaN:Not a Number:不是一个数字,但是确实是数字类型 - 垃圾
NaN参与任何算术运算结果都为NaN
NaN参与任何比较运算结果都为false - 不在三界之中
以后不希望见到undefined和NaN

2、比较运算:>,<,>=,<=,==,!=,===,!== (结果为Boolean值)

特殊
a:如果左右两边参与比较都是字符串,则是按位PK每个字符的十六进制的unicode号(十进制ascii码)
                 0-9<A-Z<a-z<汉字
                 百度搜索:中文字符集Unicode编码范围
   汉字第一个字:(Unicode4e00,Ascii码:19968);
   汉字最后一个字:龥(unicode:9fa5,Ascii码:40869);
b: NaN参与任何比较运算结果都为false,甚至不认识自己。
   解决:
     !isNaN(xx);true  ——> 有效数字
                false ——>NaN
c: undefined==null;
问题: ==区分不开undefined和null,如何区分?
解决: ===全等,要求值和数据类型都要相同,不再带有隐式转换的比较运算。
      !==,不带有隐式转换的不等比较

3、逻辑运算符:

  隐式转换:变为布尔值再综合比较
  并且:&&:全部条件都满足位true,只要一个不满足就为false;
  或者:||:全部条件都不满足位false,只要满足一个就为true;
  !:颠倒布尔值,类似于数学中的负号。
特殊:用法
 短路逻辑:只要前一个条件已经可以得到最后的结论,则后续条件不再执行。
 &&短路:
    简化了【简单的】分支结构:if(条件){操作};
    语法:条件&&(操作);
    举例:
       曾经:if(total>=500){total*=0.8};
       现在:total>=500&&(total*=0.8);
       特殊:【简单的】  ——>操作只能有一句话
             操作复杂的还是用if结构
 ||短路:
     若前一个条件位true,则后面条件不看
     若前一个条件位false,则后一个才看
     使用:两个值二选一,后期可用做浏览器兼容问题
       e=e||window.event;
       

4、位运算: 垃圾

5、赋值运算:一句话执行了两个操作,先运算,后赋值。 +=,-=,*=,/=,%=,++,--;

  何时使用:只要取出变量中的值,再做运算,之后还要再保存回去时,就使用它。
  递增:++;每次只能+1
  累加:i+几;每次想加几,随便都可以。
  
  鄙视题:++分为++ii++。
  a:  单独使用时,没有参与别的表达式,都一样
  b:  如果参与了别的表达式:
      变量中的值其实都会+1
      ++i,返回的都是递增后的【新值】;
      i++,返回的都是递增前的【旧值】。

6、三目运算:

 简化了if(){}else 和 if(){}else if(){}else
 语法:1):条件?操作1:默认操作;
      2):  条件?操作1:条件2?操作2:默认操作;

总结:

 if(){} 用&&短路
 if(){}else 用三目
 if(){}else if(){}else  用三目

建议:能用三目或者&&短路尽量不用if

扩展:

   1:舍入误差(可用作四舍五入)
    num.toFixed(n);  ——>n表示保留几位小数
   此方法会使结果变为字符串,建议搭配parseFloat使用
 
 2:获取第一个字符的ascii码:
   var ascii=str.charCodeAt(0);
   

day7

一、自定义Function:

函数:需要先定义好,可以反复调用的一个代码段。
使用:
  a: 不希望打开页面立刻执行
  b:以后可以反复的使用
  c:希望绑定再页面元素上

1:如何使用:

 1) 创建:2种
 a: 【声明方式】创建函数:
   function 函数名 (形参1,形参2,...){
                                      函数体;
                                      return 返回值;
                                                   };

b: 【直接量方式】创建函数:
    var 函数名=function(形参1,形参2,....){
                                       函数体;
                                       return 返回值;
                                                    };

2:调用

 var 接住返回结果=函数名(实参1,实参2,...);

3:举例:

 创建:function f1(){
                    console.log("我是f1");
                    };
 调用:f1();
 

4:return

 return的本意是退出函数,但是如果return后面跟着一个数据,顺便将数据返回到函数作用域的外部,
 但是return只返回,不保存,具体要不要return,全看需不需要获得函数结果。return只能在函数内部使用。

二、作用域:2种

1:全局作用域:

   全局变量和全局函数。
作用:在页面任何位置都可以使用。

2:函数/局部作用域:

  局部变量和局部函数
  特点:在【当前函数调用时,内部可以用】。
  

3:变量的使用规则:

  优先使用自己的,自己没有找全局,全局没有就报错。
 
 特点:缺点
   1);千万不要在函数种对着未声明的变量直接赋值,会导致全局污染
     解决:尽量变量使用前都先var一下
   2):局部可以用全局的,但是全局不能用局部的
     解决:搭配上return

4:声明提前 ——>鄙视题

   在程序正式执行之前
   将var声明的变量(轻)和function【声明的】函数(重)都会集中定义在【作用域的顶部】,但是都会将【赋值留在原地】。
   【声明方式】创建的函数会【完整的提前】。
   【直接量方式】创建的函数不会完整提前,只有【变量部分提前】。
   
   都不会使用,只会在鄙视题种遇到,遵守以下几个规则:
   a:变量名和函数名尽量不重复
   b:先创建后调用
   c:如果鄙视时,遇到先使用后创建,多半是考声明提前,先转换为我们认识的代码,再去判断。

5:按值传递:两个变量之前进行赋值

  如果传递的是【原始类型】的值:修改一个变量,另一个变量不会受到影响。
  如果传递的是【引用类型】的对象:修改一个变量,另一个变量也会受到影响,两者使用的是 同一个地址值(浅拷贝)。
  

三、预定义全局函数:

1:编码和解码:

 问题:url中不允许出现多字节字符,如果出现就会乱码
      utf-8编码格式下,一个汉字就是3字节字符
 解决:发送前,前端将多字节字符编码为单字节字符(数字/字母)
      发送后,后端将单字节字符解码为多字节原文。
 
 如何:
     编码:var code=encodeURIcomponent(str);
     解码:var 原文=decodeURIcomponent(code);

2:isFinite(num):

    判断num是不是无穷大:true ——>有效数字
                       false ——>无穷大
     哪些为false?
           NaN,Infinity,分母为0

3:牛逼的: parseInt/parseFloat/eval/isNaN

四、分支结构: if分支/switch分支

1:switch语法:

   switch(变量/表达式){
                     case1:
                     操作1break;
                     case2:
                     操作2break;
                     default:
                     默认操作;
                            }

特殊:

    1case的比较不带有隐式转换
    2:问题:默认只要一个case满足后,会将后面所有的操作全部做完
       解决:在每个case操作后面都加一个break3:有些地方可以不加break;
       a: 最后一个操作default后面可省略;
       b: 若中间多个条件,做的是一样的操作,也可省略;

if VS switch区别:

   1switch...case:
       缺点:必须要知道结果后才能使用,不能作范围判断。
       优点:执行效率相对较高。
   2if...else:
       缺点:执行效率相对较低。
       优点:可用作范围判断。

建议:

   代码优化,尽量将if...else换成switch...case或者三目或者&&短路。

day8

一:循环结构

1、while循环:

 1): var 变量名=几次;
      while(循环条件){
                     循环体;
                     变量变化;
                           };  ——>一般用于不确定循环次数。

 2): var 变量名=几次;
     do{循环体;变量变化;}while(循环条件);

鄙视或者面试:

 do...whilewhile的区别:
   如果第一次都不满足,while什么都不执行,do...while至少会执行一次。

2、for循环:

  for(循环变量;循环条件;变量变化){
                                 循环体};  ——>明确循环次数

3、退出循环:

 break;  ——>退出整个循环
 continue;  ——>退出本次循环,根据需求来判断需不需要执行后面的循环。

二:数组的基础

1:概念:

  含义:在一个内存(变量)中保存了多个数据的一个集合结构
  何时:只要存储多个相关数据,都要用数组集中保存
  作用:一个好的数据结构,可以极大提升开发效率

2:创建:2种

  **a:直接量:    var arr=[值1,值2,....];
    b:构造函数:  var arr=new Array(值1,值2,...);
        缺点:var arr2=new Array(5);创建了一个长度为5的空数组,不用。

3:访问/调用:

   console.log(arr[下标]);  ——>下标的当前元素
   
遍历整个数组:
   for(var i=0;i<arr.length;i++){
                                 console.log(arr[i]);
                                                    };

特殊:

  a:读取元素,下标越界  ——>返回为undefined
  b: 添加元素,下标越界  ——>下标不连续,导致稀疏数组。

4:数组的三大不限制:

  a:不限制长度;
  b:不限制类型;
  c:不限制下标越界。

5:数组的唯一属性:

  数组名.length;   可以获取数组的长度。
  
  3个固定套路:
    1)末尾添加:       arr.[arr.length]=新值;
    2) 获取倒数第几个:  arr[arr.length-几];
    3)删除倒数n个:    arr.length-=n;

6:遍历数组: 对数组种每个元素进行相同或者相似操作

    for(var i=0;i<arr.length;i++){
                                  console.log(arr[i];  ——>当前下标元素
                                      };

7:如何释放一个引用类型:

 看清楚这个引用类型的数据有几个变量引用着,每个变量都要释放后,才能释放干净。
 建议:代码都要封装到一个函数种,函数中变量会自动释放。

8:索引数组

 下标都为数字组成的数组。
 关联(hash)数组:下标都可以自定义

hash使用:

 1)  创建:2a: 创建空数组: var arr=[];
   b: 为数组添加自定义下标并添加元素值: arr["自定义下标"]="新值";
 
 2)  访问/调用:
       console.log(arr["自定义下标"]);
   
   强调:hash数组的length永久失效为0!!!
   
 3)  遍历hash数组:
      for(var i in arr){
                       console.log(arr[i];
                                          };

建议:索引数组依然使用for循环,hash数组用for...in。

4)hash数组的原理:
   hash算法:将字符串计算出一个尽量不重复的数字(地址值),字符串内容相同,则计算出来的数字也一定相同。
   添加元素:将自定义的下标交给hash算法,得到一个数字(地址值),把添加的元素保存到了这个地址值之中。
   读取元素:将指定的自定义下标交给hash算法,得到一个和添加时完全相同的数字(地址值),根据地址值找到之前保存的东西。

5) js里面的一切东西都是对象,除了undefined和null
    【一切对象的底层都是hash数组】
    

三:Array的API:函数,只有数组才可以使用。

1:arr to string:

var str=arr.join("自定义连接符");

 固定套路:
 1):鄙视题:将数组内容拼接在一起,形成一句话/单词。
     无缝拼接:var str=arr.join("");
 2): 将数组的元素拼接为DOM页面元素
     举例:
      //数据
      var arr=["-请选择-","北京","南京","西京","东京","重庆"];
      //转为字符串拼接
      var str="<option>"+arr.join("<option></option>")+"</option>";
      //渲染到DOM树上
      sel.innerHTML=str;
   

2:数组拼接:添加新元素方式:

根据你传入的实参全部拼接到arr的末尾
 var newArr=arr.concat(新值1,新值2,...);

特殊:

1): 不能修改原数组,只会返回一个新数组;
2): concat支持传入数组参数,悄悄的将你传入的数组打散为单个元素后拼接。

3:截取子数组:

根据你传入的开始下标,开始截取,一直到结束下标。
var subArr=arr.slice(starti,endi);

特殊:

1): 不修改原数组,返回一个新数组
2):含头不含尾  ——>解决:var subArr=arr.slice(starti,endi+1);
3):endi可以省略不写,会从starti位置一直截取到末尾;
4):其实两个实参都可以不写,从头截取到末尾(深拷贝),与之前按值传递(浅拷贝)不同。

4:删除、插入、替换:

删除:var dels=arr.splice(starti,n);  //n表示删除的个数,删除几个的意思

特殊:
其实splice也有返回值,返回值时删除的元素组成的新数组。

插入:var dels=arr.splice(starti,0,值1,值2,...);

特殊:
1):插入新的元素会将原有的数组和后续元素挤到后面去;
2):插入也有返回值,只不过没有删除元素,因此为空数组;
3):千万不要插入一个数组,会变成一个部分二维数组。

替换:var dels=arr.splice(starti,n,值1,值2,...);
n代表删除的个数。

特殊:
删除的元素个数不必与插入的元素个数一致。

5:翻转数组:

arr.reverse();  ——>不用

四:二级联动:

1):select的专属事件:onchange; //状态改变事件:只有选中项发生变化才会触发
2):select的专属属性:selectdIndex;  //直接获取当前选中项下标
3):必须用到二位数组(再次细分)。

day6

一:Array API:

1:排序:2种方法

鄙视时:手写冒泡排序
     公式:
       for(var j=1;j<arr.length;j++){
                         for(var i=0;i<arr.length-j;i++){
                                  if(arr[i]>arr[i+1]){
                                        var middle=arr[i];
                                          arr[i]=arr[i+1];
                                          arr[i+1]=middle;
                                                          }
                                                       }
                                                    }
                      console.log(arr);

  

2: 正式开发中:数组提供了排序的API

arr.sort();
问题1:默认将数据们转为字符串,按位PK每个字符的Ascii码,如果希望按照数字排序怎么办?
     解决:
       arr.sort(function(a,b){
                       console.log(a);  //后一个数字
                       console.log(b);  //前一个数字
                       return a-b;      //如果return返回是个正数,那么说明后面比前面的大
                                        //如果return返回是个负数,那么说明前面比后面的大
                                        //如果return返回是0,那么说明前面后面一样大
                                        //而sort方法就是根据你返回的数字来判断要不要交换位置

问题2:如何降序排列?
     arr.sort(function(a,b){
                          return b-a;
                                   });
                                   
 强调:排序非常重要,只要以后网页有任何排序功能,它底层一定是一个数组,因为只有数组才可以排序。

3:栈和队列:添加元素和删除元素的新方式。

栈:其实就是一个数组,只不过一端封闭,只能从另一端进出的数组。
    何时:优先使用最新的数据。
    如何:
      开头进:arr unshift(新值,...)  //添加元素新方式,向前添加
                                    //缺点:会修改其它元素的下标,不能传入数组
      开头出:var first=arr.shift();  //删除元素新方式,向前删除,一次只能删除一个
                                     //缺点:修改其他元素的下标。
  *** 结尾进:arr.push(新值,...);  //添加元素的新方式,向后添加
                                  //完美替代了arr[arr.length]=新值 和 arr=arr.concat(新值),不能传入数组
                                  
     结尾进:var last=arr.pop();  //删除元素新方式,向后删除一个,一次只会删除一个。
     
   搭配使用:
                    开头进:arr.unshift(新值,...);
		    结尾进:var last=arr.pop();

	         *结尾进:arr.push(新值,...);
		 开头出:var first=arr.shift();
 

二:二维数组:数组的元素又引用着一个数组。

   何时:在一个数组内,希望再次细分每个分类
   创建:
       var arr=[                 ["张三丰",128,5500],
                 ["张翠山",38,4500],
                 ["张无忌",18,3500]
                                    ];
                                    
   访问/调用:
      arr[行下标][列下标];
      
      特殊:
         列下标越界,返回为undefined
         行下标越界,报错

遍历二维数组:

 必然两层循环,外层循环控制行,内层循环控制列。
     for(var r=0;r<arr.length;r++){
                      for(var c=0;c<arr[r].length;c++){
                                 console.log(arr[r][c]);
                                                       }
                                                         };
                        

三:string的基础概念;

含义:多个字符组成的【只读】字符【数组】 ——>不会修改原字符串

1):和数组相同的地方:
    a:字符串中的个数:str.length;
    b: 获取字符串某个字符:str[i];
    c:遍历字符串
    d:所有数组不能修改原数组的API,字符串都能使用 ——>(concat(还不如+隐式转换拼接)、slice)。
2):和数组不同的地方:
    所有数组直接修改原数组的API,字符串都不可以使用,比如排序只有数组可以使用
     字符串也有很多属于自己的API
     

引用/对象类型:11个

   String\Number\Boolean   ——>它们三个拥有包装类型
   *Array\*Function\Date\Math\*RegExp(正则:验证)\Error\*Object\Global(全局对象,在浏览器中被window对象给代替罢了)

包装类型:

含义:专门将原始类型的值封装为一个引用类型的对象
为什么:原始类型的值原本是没有任何属性和方法,本身不支持操作,为了方便我们对这个三个进行操作,提供了包装类型。
何时使用:只要试图用原始类型的变量调用属性和方法时,自动包装。
何时释放:方法调用完毕后,自动释放包装类型,并且返回数据。
  undefinednull不能使用 ——>没有提供包装类型

扩展:

1:事件:onmouseover   鼠标移入
        onmouseout    鼠标移出

2:开启定时器:
   timer=setInterval(function){
       操作
            },间隔毫秒数);

3: 停止定时器:
   clearInterval(timer);

day10

一:只读:

1、String API:可以直接使用,只有字符串才可以用

1):转义字符: \
     作用:
        a:将字符串中和程序冲突的字符转为原文
            比如:双引号中还想放入双银行 "\""
        b: 包含特殊功能的符号: ——>几乎没用
           \n:字符串换行
           \t: 制表符——大空格tab
        *c: 输出unicode编码的字符——>搭配正则
        \uxxx: 第一个汉字:\u4e00       ascii码:19968
                最后一个汉字:\u9fa5     ascii码:40869

2、大小写转换:将字符串中每个英文字母统一转为大写或者小写

何时:只要程序不区分大小写,就要【先统一】的转为大写或者小写,再比较(验证码)
如何:
    大写:var upper=str.to Uppercase();
    小写:var lower=str.to Lowercase();

3、获取字符串中指定位置的字符。

var newStr=str.charAt(i)  还不如str[i]

4、获取字符串中指定位置的字符的ascii码

var ascii=str.charCodeAt(i);  搭配上循环,我们可以得到每一个字的ascii码
  根据ascii码转回原文:
     var 原文=String.from CharCode(ascii);

5、检索字符串,检查索引,获取关键字下标

var i=str/arr.indexOf("关键字",starti);
从starti位置开始,查找右侧【第一个关键字】的位置
 starti可省略,默认从0位置开始查找
返回值:找到了,返回的是第一个关键字的第一个字符的下标
       **没找到,返回-1,不关心下标为多少,只关心为不为-1
  作用:以后只希望判断有没有或者不希望有重复的
  强调:数组也能用此方法,老IE不支持
  
鄙视题:默认只能获取到第一个关键字的下标,如何才能获取所有关键字下标?
    var i=-1;
      while((i=str.indexOf("no",i+1))!=-1){
                       console.log(i);
                                     };

6、截取子字符串:3种

   **var subStr=str/arr.slice(starti,endi+1);  //和数组用法一样
     .substring(starti,endi+1);  //用法几乎和slice相同,但不支持负数
     .substr(starti,n);  //支持负数,n代表截取几个数,不考虑含头含尾
   

7、拼接字符串

   var newStr=str.concat("新字符串");     ——>不如+运算
   

8、*替换字符串

   var newStr=str.replace("关键字"/RegExp,"新内容");

9、切割/分割字符串****

作用:将字符串转为数组
  var arr=str.split("自定义切割符");
  
 特殊:
   a:切割后,切割符就不存在了
   b:切割符是一个空字符串"",切散每一个字符
   

扩展:

  1:创建元素:
     var elem=document.createElement("标签名");
  2: 为它设置必要的属性或者事件:
     elem.属性名="属性值";
     elem.onclick=function(){操作};
  3:渲染到DOM树上/上树:
     父元素:appendChild(elem);