第二周js学习总结

128 阅读16分钟

第一天:

一.数据类型的转换:

   一.强制转换:31.转字符串:
            x.toString()
            String(x)
            这个方法不太重要,因为页面赶上获取到的一切东西都是字符串类型的数据
        2.转数字:
            parseInt()
            parseFloat()
            Number
            
        --以上两个是第一周的时候已经学过的,请自行复习--
        
        
        
        3.转布尔:
           Boolean(x)
           这个方法是万能的,任何类型都可以转为布尔值,但是布尔值只有两个结果,一个是true,一个是false:
           极大部分情况这个结果都是true,所以我们只需要记住以下x不为六个就不会为false0 "" undefined null NaN false;
           这里要注意,在分支或者循环的判断(条件)中,不管出现了什么东西,只要不是以上六个兄弟,那么他们就都应该判定为true。
           
           
           
   二.隐式转换:
       都出现在运算符中
           算术运算符
               默认转为数字,再进行运算:
                   要注意字符串、布尔等特殊的情况
                   true->1
                   false->0
                   undefined->NaN
                   null->0
                   字符串->如果本身是纯数字就会转为数字进行运算,如果不是就要用转数字的方法,但不识别数字以外的字符,而且会出现NaN的情况
           比较预算符
                   默认转为数字在进行比较大小
           --以上注意都是第一周的时候已经学过的,请自行复习--

二.运算符和表达式:

   一.算术运算符:
       + - * / %
       需要注意其中的%和+号的特殊点
       --以上两个是第一周的时候已经学过的,请自行复习--
           
           
           
   二.比较运算符:
       > < >= <= == != === !==
       结果:布尔值
       隐式转换:默认转为数字在运算
               1.注意:如果参与比较的两边都是字符串,那么就会默认对位比较该字符的十六进制unicode号(十进制ascii码)
               数字:48-57
               大写字母:65-90
               小写字母:97-122
               汉字:19968-40869
                     e400-9fa5
              2.NaN参与任何比较运算结果都为false,解决:!isNaN(x)
              3.undefined==null
              这个比较的结果会是true,他们要进行区分的话就要使用===
              ===全等于:
                  不仅要左右两边的值相等,而且要左右两边的数据类型也相等才能为true
                  56==="56"//flase
               !==不全等于
    三.逻辑运算符
        与  &&
        或  ||
        非  !!
            短路逻辑:
                原理:如果前一个条件可以得出结论,就不需要再向后读取了
                1.与的短路逻辑:
                    我们通过与(&&)的条件去看,如果前一个(从第一个开始)的结果为true,我们就还需要继续判断后面的是不是也为true才能让整体为true。但是,如果一开始或者说前一个为false,那么在与(&&)的必要条件(全部满足才为true)中,那么就可以判断这个整体是为false的,就不用往后继续读取条件判断了
                     
                    &&短路:
                        
                        目的:简化【简单的】if分支:一个条件一件事,满足就做不满足就不做
                        简化:条件&&(操作);
                        原来:if(total>=500){total*=0.8}
                        现在:total>=500&&(total*=0.8)
                2.或的短路逻辑:
                    或本身的要达成true的结果需要有一个条件为true就为true,所以前一个如果为true,后面就不用再读取了,可以解决代码的浏览器兼容问题
                    ||短路:
                        e=e||window.event;
                        二选一,前一个不兼容,失败,后一个继续判断
    四.位运算:                      
       左移m<<n:m左移了n位-->m*2的n次方
       右移m>>n:m右移了n位-->m/2的n次方
    五.赋值运算:
        += -= *= /= %=
        一个操作完成了两件事,先计算,再赋值回去
        i++和i+=1区别:
            前一个叫做递增,每次只能加一
            后一个叫做累加,可以加其他的
        ++i(前加加)和i++(后佳佳)的区别
            单独使用两者没有区别
            如果参与了别的表达式,变量i虽然都会加1
                但是前++会在表达式中使用i加完1之后的新值
                后++会在表达式中使用i加完1之前的旧值
    六.三目运算:
        目的:简化if...elseif...esle if....else
        语法:
            1.条件?操作1:默认操作;
            2.条件1?操作:条件2?操作2:默认操作;

拓展:

        1.计算机的摄入误差,出现在小数的计算上,要在此时取四舍五入或者小数的几位计算,可以将结果x.toFixed(d),d代表小数点后几位,配合paseFloat()使用效果更好哦,因为前面那个的转化会变为字符串
        2.获取字符串的ASCII码
            str.charCodeAt(i)
    

第二天

一.自定义函数Function:

函数,也成为方法,是需要提前定义好的,可以反复使用的代码段
    1.创建函数的方式:21.声明方式:--不是人人都有声明方式,但是有声明方式的人一定优先使用声明方式,因为最简单--只有三个人有:变量、常量、函数--
            function 函数名(形参列表){
                函数体;
                return 返回值;
            }
        2.直接量方式:--大部分人直接量激素最简单创建方式了
        var 函数名=function(形参列表){
        --可以看出函数名其实也是一个变量名--
        --衍生出:elem.on事件名就是函数名
            btn.onclick=function(){}
            不过长了点--
            
            函数体;
            return 返回值;
        }
       return:
           退出函数的意思
           不过return后面再跟上一个数据,这个函数在return的作用下就会在推出函数的时候将这个值保存在函数上返回到全局中,但是,在函数里面,你得到这个数据的时候,return只负责返回值,不负责保存这个值,所以要返回一个值之前,在函数里用一个变量去接住这个需要被返回的值
           例如:
                       function calc(){
                           var a=1,b=1;
                           var c=a+b
                           return c;
                       } //这个时候我返回了c这个函数的结果就是c;如果直接写end=c+1 就会错误,在外面直接使用c是用不到c的,所以
                       var d=calc();
                       end=d+1
                       这样就可以计算了
          调用函数:var result=函数名(实参列表) 

二.作用域:2种

1.全局作用域:成员:全局变量和全局的函数,也就是最外层创建的东西,在任何位置都可以使用调取
2.函数/局部作用域:成员:局部变量和局部函数,也就是在一个函数之内创建的变量函数这些,只能在当前函数内使用
变量使用规则:
    优先使用局部自身的变量,如果没有,就一层一层往上找,如果全局都没有,就报错
    特殊:
        1.不要对着没进行什么也就是没var的变量直接赋值:a=1;这会导致全局污染,全局本身没有,你在局部直接这么写,就会吐痰给全局加上一个内存
        2.局部的东西,全局无法使用,这时需要return,要用那个变量,return返回哪个,记得保存
        3.如果没写return也会悄悄出现一个return,值是undefined(默认的这是)
        4.return一般只出现在函数的最后,只能一个函数写一次
        5.以前学的方法,大部分底层都有return操作
声明提前:
    程序在正式执行之前
    会将所有的var声明和function声明的函数集中提前
    提前到【当前】作用域的顶部,但是【赋值】本身会留在原地
    变量比函数轻

    我们自己写绝对不会碰到,只要遵守规则:1.先创建再使用2.变量名和函数名尽量的不要重复
    只会在笔试中碰到:如果以后你碰到先使用后创建,多半都是在考你声明提前
按值传递:
    如果传递的是【原始类型的值】:
        var a=0,b=a;
        a++;
        b还是为0
        修改一个变量,另一个变量是不会受到影响的,其实是复制了一个【副本】给对方

    如果传递的是【引用类型的对象】:Array、Function
        var a=[1,2,3,4],b=a;
        a.length-1;
        两个都会变
        修改一个变量,另一个变量是会受到影响的,因为两者使用的是【同一个地址值】

三.预定义全局函数:

前辈们提前创建好的,可以直接使用的,在哪儿都可以调用
1.编码和解码:
    问题:url属性中不允许实现多字节字符,如果出现了就会乱码
    utf编码格式下,一个汉字,占3节字符
    解决:发送前,将用户输入的多字节字符转为单字节字符
    发送后解码为原文
    
    编码:var code=encodeURIComponent("原文");
    解码:var 原文=decoudeURIComponent("code");
    
    但是因为某次浏览器更新,浏览器自带此功能,所以不需要我们写了
2.isFinite(num);判断num是不是无穷大,为true就是有效数字,为false就是无穷大  
    NaN 分母是0的表达式 Infinity 这三个为false
3.常用的
    parseInt/Float isNaN eval()
    eval(x)将x表达式转化为数字类型

四.分支结构:

switch分支和if分支
语法:
    switch(变量/表达式){
        case1:
        操作1;
        case2:
        操作2;
        ...
        default:
        默认操作
    }
特殊:
    1.case的比较不带隐式转换
    2.默认case满足第一个条件,操作做完成后,也会向下继续读取,需要在每行机上break;最后的default不用写break,在中间如果值不同,操作一样,可以省略操作和break不写,在最后一个写就可以了;
if vs switch
    1switch...case...,缺点:必须要知道最后的结果是什么才可以使用,在case中不能做范围判断,只能做等值判断
			 优点:执行效率相对较高
2if...else:缺点:执行效率相对较低
              优点:可以随意的做范围判断

第三天

一.循环结构:

1.do...while
    语法:
        var 变量=几;
        do{
            循环体;
            变量变化;
        }while(循环条件)
    它与while循环的区别:
        如果第一次条件都满足,那么都没有区别
        如果第一次都不满足,那么while一次都不执行,do...while会执行第一次
2.退出循环:
    之前学的break;是退出整个循环,相当于中止;
    continue;推出本次循环,相当于跳过本次循环;

二.数组的基础:

1.基础概念:
    一个变量保存着多个数据的一个集合
    只要存储多个相关数据,都要用数组保存
    一个好的数据结构,可以极大的提升程序员开发效率
2.创建:
    直接量方式:var arr=[...]
    构造函数:var arr=new Array(...)
        这个方式有一个坑,如果...只有一个数值而且是数字,那么他并不会创建一个保存有这个数字的数组,而是创建一个长度为这个数值的空数组
3.访问
    添加/修改
    下标越界
4.数组三大不限
5.数组唯一的属性:长度
6.遍历数组
------------------第一周复习------------------
7.如何释放引用的类型:我们说一个变量被创建就是创建了内存,为了减轻浏览器占用cpu的性能,在所有人结束引用这个变量的时候,应该在最后将内存释放掉,手动释放是将声明的变量赋值为null就可以了,所以要有封装函数的思想,因为函数会自动释放在函数内部创建的变量,只有调用函数才能占用
8.关联(hash)数组:
    下标都是可以自己定义的数据
    一般我们创建的正常数组下标都是数字,从0开始,这也叫做索引数组
    关联数组的使用:
        1.创建:
            创建一个空数组 arr=[]
            然后为这个空数组添加自定义下标以及内容:arr["自定义下标"]=新值
        2. 访问
            arr["已经添加过的自定义下标"]
        3. 注意:hash数组的length永远失效了,为0
                遍历hash数组,使用for...in循环
                    for(var i in 数组名){
                        i会自动得到下标
                    }
                    这是一个很强的功能,自动化遍历的感觉,不需要再设置i的条件了
        4.hash数组的原理:
            它会将字符串计算出一个尽量不重复的数字(地址值)
            字符串的内容如果相同,计算出来的数字也会一样
            添加元素:将自定义下标交给了hash算法,得到了一个数字(地址值),直接将你要保存的数据放到了此地址
	    获取元素:将指定的自定义下标交给hash算法,得到一个和当初添加上完全相同的数字(地址值),通过地址就可以找到你当初保存的数据
        5.js里万物皆对象,除了undefinednull【一切对象的底层都是hash数组】

三.数组的API

1.数组转字符串
    var str=arr.join("自定义连接符");
    
    固定套路:2个
        1.将数组的内容进行无缝拼接为一段话
        arr.join("");
        就可以了
        2.将数组里面的数据拼接为DOM页面元素
            //数据
            var arr=["请选择""北京","南京","西京","东京","重庆"]
            //将数组变为字符串并且完善标签
            var str="<h1>"arr.join("</h1><h1>")+"</h1>"
            //渲染上树
            bd.innerHTML=str
 2.拼接数组:添加元素的新方式
     上周学习的是arr[arr.length]=新值,但是这只能一次加一个
     var newArr=arr.concat(新值1....);
     特殊:1.不会修改原数组,拼接新内容之后arr.concat(新值1....);会有一个新数组,但是这个数组需要保存到一个新变量
         2.可以直接传入一个数组,但是它会被打散成一个个的数据传入
 3.截取子数组:
     //根据你选定的开始下标到结束下标,但是这个api在截取时候不会包含结尾下标
     var newArr=arr.slice(strati,endi+1);
     特殊:1.不修改原数组,需要保存返回的新数组
         2.含头不含尾,所以想要截取到的endi加1就可以了
         3.endi可以不写,从开始到末尾
         4.两个都可以不写,从头截取到尾
         5.两个参数支持负数 -1代表倒数第一个
------------------------以上三个不会修改原数组,需要用新变量保存----------------------------
4.删插替
    删除:var dels=arr.splice(starti,n)
    n代表删除几个
    这个dels是删除的元素组成的新数组,而arr本身就没有了这几个数据
    插入:arr.splice(starti,0,新值1,2,...)
    删除0个就可以插入了,但是不要插入一个数组,它不会打散数组,而是变成有一维数组和二维数组的复杂玩意儿,插入了多少个新值,本来在starti后面的值下标后移
    替换:var dels=arr.splice(starti,n,值1,....)
    删除n个再添加就是替换,这个n和添加的值不必相等,可以多加或者少加
5.反转数组:arr.reverse();

拓展:select元素的专属事件,也要找到它再用

    select.onchange=function(){}
    只有选中的那个发生了变化才触发的事件
select元素的专属属性,也要找到它再用
    select.selectedIndex选中项的下标

第四天

一.排序:

    1.手写冒泡排序
        for(var j=0;j<arr.length-1;j++)
            for(var i=0;i<arr.length-j-1;i++){
                if(arr[i]>arr[i+1]){
                    var m=arr[i];
                    arr[i]=arr[i+1];
                    arr[i+1]=m
                }
            }
    2.数组排序
        arr.sort();
        这个排序方式是默认将arr的元素按位pk每个字符的ascii码进行排序
        按数字顺序排序的话:
            arr.sort(function(a,b){//匿名回调函数
                return a-b;
            })//这是从小到大排列,从大到小就是b-a
            //这个a其实是后面一个数字a从下标1开始带入
            //b是前面一个数字b从下标0开始
         注意:排序非常之重要,页面只要有排序功能,那么就说明它的底层一定是一个数组,因为数组才能排序
   3.栈和队列
       栈就是数组,不过是一端关闭,只从一端进出
       当你想优先使用最新的数据时,就用到了栈
       从开头添加新元素arr.unshift(新值1...)
       开头删除元素var first=arr.shift()删除一次只能删除一个,删除的可以保存起来使用,只是原数组没了而已
       从末尾添加元素arr.push(...)
       从末尾删除var last=arr.pop(),跟上面删除用法一样
       队列,也是数组,不过是一端进一端出
       1.arr.unshift(...)
       arr.pop()
       2.arr.push(...)
       arr.shift()
      
 ------------------------ES3数组API就到这儿-----------------------      

二.二维数组:

 一个数组内的元素也是数组
 何时使用:    在一个数组内要对元素进行细分分类
 创建:    var arr=[[1,2,3],[wang,li,zhang]];
 访问:    arr[行下标][列下标];
     列下标越界会得到undefined
     行下标越界就会报错
     
 遍历:    必定需要两次循环,第一层循环找行,第二层循环找列
     for(var r=0;r<arr.length;r++){
	for(var c=0;c<arr[r].length;c++){
		console.log(arr[r][c])
	}
     }

三.字符串Sting的概念:

 多个字符组成的【只读】字符【数组】(只读说明不会修改原字符串)
 和数组的相同点:
     1.字符串中的长度:str.length
     2.获取字符串中某个字符:str[i];
     3.遍历字符串
     4.所有数组不修改原数组的API,字符串可以使用(concat,slice)
 不同点:  
     数组会修改原数组的API,字符串都不可以使用
     字符串有很多自己的API

四.引用/对象类型的概念:

String Number Boolean -->这三个原始值类型的数据被前辈们用包装类型给包装成了对象类型,而且它是在你试图用属性和方法的时候自动将它包装成可以使用属性和方法的对象类型,使用完之后的结果又会自动释放,变回原来的原始值类型
Array Function Date(日期) Math(数学) RegExp(正则)
Error(错误)
Object(面向对象的开发方式)
Global(全局对象)-->在浏览器中,它被window代替了,而window可以省略不写,但是全局对象是它,只有js中global被代替了,其他语言里都是这个

扩展:轮播图的实现

    计时器:timer=setInterval(function(){
        操作;
    },间隔毫秒数)
    停止计时器:clearInterval(timer)
    鼠标移入/移出事件:onmouseover/out

第五天

一.功能符 \:

    1. \  可以在字符串中将一些与程序语言冲突的字符转为原文
    2. \n 可以使字符串在js中换行
       \t 大空格
    3.\uxxxx \u加上unicode码可以输出字符

二.转换大小写:

    将所有字符转为大写或者小写
    主要用于验证码的对比上,只要程序不区分大小写,那么我们就先统一转为大写或者小写,然后对比,因为大小写的unicode码不一样
    转大写:str.toUpperCase
    转小写:str.toLowerCase

三.获取字符串中指定位置的字符:

    str.charAt(i)   这个不如直接str[i]

四.获取字符串中指定位置的ASCII码 :

    var ascii=str.charCodeAt(i);
    通过ascii码转回原文
    var 原文=String.fromCharCodeAt(ascii码)

五.检索字符串:

    var i=str/arr.indexOf("关键词",starti);
    starti可以省略,不写从下标0开始查找
    找到了就返回i,只找第一个的
    没找到返回-1
    这个没找到的返回值-1,可以帮助我们判断有没有这个数字
    找到字符串中所有关键词的下标位置,
        var str="no zuo no die no can no bibi";
                var index=-1;//开始位置 -1
                while((index=str.indexOf("no",index+1))!=-1){
                        console.log(index);
                }

六.截取字符串:

 var news=str/arr.slice(starti,endi+1)
          str.substring(starti,endi+1)  不如上面一个,不支持负数
          str.substr(starti,n)     从第几个开始,截取几个,不用考虑含头不含尾的情况,而且这个starti支持负数

七.拼接字符串:

 var news=str.concat(...);  不如直接+""

八.替换字符串:

  强大的功能,但是现在没学正则
  var news=str.replace("关键词/正则表达式","新内容")

九.分割字符串:

 作用:将字符串变为数组,与数组的join()一起实现字符串数组的互换
 var arr=str。split("自定义切割符")
 注意:切割后切割符就不在了,字符串变成数组
     如果自定义切割符不写,就会切散每一个字符变成数组中的元素
     
     
     

拓展:

  1.js创建空标签
      var elem名=document.createElement("标签名");
  2.设置必要的属性和事件
      elem名.属性名=:"属性值";  
      elem名.on事件名=function(){操作}
  3.上树
      父元素.appendChild(elem名)