学习JS第二周总结

62 阅读11分钟

数组的基础②

创建数组 var arr = [值1,...];
        var arr = new arr(值1,...);
第二种方法有一个坑:new arr(num);表示创建一个长度为num的空数组,里面没有任何东西,只有无数的undefined
题1:按值传递:var a=x; var b = a; 修改a,b变不变,或者修改b,a的值变不变?
    答:如果传递的是原始类型,其实是复制了一个副本给对方,两者是互不影响的。
        如果传递的是引用类型,其实是把自己的地址值给了对方,而两者是同一个地址值,一个修改,另一个也会修改
        因为引用类型很大,比原始类型大的多,不可能保存在变量本地,只是保存了一个地址值而已。
        引用类型在比较时,其实看的不是值,而是地址值在作比较。
题2:如何释放一个引用类型?一定要看清楚有几个变量引用着这个引用类型,每个变量都要释放后才能释放干净!
    因为在JS底层有一个垃圾回收器,只有垃圾回收器的计数器为0的时候才会删除不要的数据。
    建议:代码都要封装在一个函数内,函数中的一切变量都会释放。
    索引数组:下标都是数字组成的数组。
**hash数组**
    下标是可以自定义的
    为什么:索引数组的下标无具体意义,不便于查找
    如何使用:
        1.创建:2步
            先创建一个空数组:var arr = [];
            为数组添加自定义下标并且赋值:arr["自定义下标"] = "新值";
        2.访问:arr["自定义下标"]
        3.强调:hash数组的length会失效,永远为0!
          遍历hash数组不能再使用for循环了,必须使用for in 循环;for in它不需要设置从哪里开始,到哪里结束,纯自动化的,专门为了遍历hash数组而存在的。
        4.for in 语法:
            for(var i in arr){
                    i -> 下标
                    arr[i] -> 当前元素
            }
            for in 不仅可以遍历hash数组,还可以遍历索引数组。
**JS里面的一切东西都是对象,除了undefined和null。一切对象的底层都是hash数组。**
** 数组的API**
    1. arr to str
        var str = arr.join("自定义连接符");
    笔试题:将数组里面的内容拼接成一段话/单词的无缝拼接,其实就是拼接了一个空字符串。
    拼接数组:
        将你传入的实参全部拼接到数组的末尾
        语法:var newArr = arr.concat(值1,...);
        特殊:1.不修改原数组,只会返回一个新数组
             2.concat支持传入数组参数,悄悄的将传入的数组打散为单个元素再拼接
    截取子数组:
        只想要取出数组的某一部分使用
        语法:var subArr = arr.slice(starti,endi+1);
        特殊:
            1.不修改原数组,只会返回一个新数组
            2.含头不含尾
            3.endi可以省略不写,表示从starti截取到末尾
            4.starti和endi都可以省略不写,那么从头到尾完整的复制一份,此操作
            也叫做深拷贝!复制了一个副本给对方,两者互不影响。
            5.支持负数参数,-1代表倒数第一个
            
    2.以下所有的API都会直接修改原数组
    **删 插 替**
    删除:var dels = arr.splice(starti,n);//n代表你要删除的几个
    特殊:虽然它直接修改原数组,但是也有返回值,返回的是被删除数组组成的一个新数组。
    替换:var dels = arr.splice(starti,n,新值1,...)
    特殊:插入的元素和删除的元素,个数不必相等
    插入:var dels = arr.splice(starti,0,新值1,...);
    特殊:1.原stari位置的元素以及后续元素都会向后移动
         2.尽量不要插入一个数组,会导致我们的数组一些是一维,一些是二维,导致我们遍历的时候极不方便。
    **翻转数组**:arr.reverse();
        例如:var arr = [2,9,5];
              arr.reverse();
              console.log(arr);//[5,9,2]
    **数组的排序**         
    语法:arr.sort();
    默认:将数组中的元素转为字符串,然后按位PK每个字符的Unicode号(ASCII码)
        问题1:希望将数字升序排序:
            arr.sort(function(a,b){
                return a-b;
            })
            此函数叫做匿名回调函数
                如果a-b>0;说明后一个大于前一个
                如果a-b<0;说明后一个小于前一个
                两者相等时,不需要交换位置
        问题2:希望按照数字降序排序:
            arr.sort(function(a,b){
                return b-a;//前一个数减后一个数
            })
        强调:1.以后只要在网页上发现有排序功能,说明他的底层一定是一个数组,因为JS里面只有数组可以排序。
             2.以后只要在网页上发现有随机功能,说明它底层一定有随机公式。
  **添加元素和删除元素的新方式:**
       arr.unshift(a,b,...);//添加元素,向前添加,添加到第一个元素的前面一个位置。缺点:导致其它元素的下标发生改变
       arr.shift();//删除元素的新方式,向前删除,一次只能删除一个,也有返回值,返回的是删除的那个元素。缺点:导致其它元素的下标发生变化。
       arr.push(a,b,c...);//添加元素,向后添加,添加到最后一个元素的后面。
       arr.pop();//删除元素,向后删除,一次只能删除一个,也有返回值,返回的是删除的那个元素。
  **ES5提供的3组6个API:**
      1.判断:2个,判断的结果一定是一个布尔值
          every:每一个,要求所有的元素都满足条件,结果才为true,只要有一个不满足则为false
          语法:var bool = arr.every(function(val,i,arr){
                      //val - 当前的值
                      //i   - 当前值的下标
                      //arr - 数组的本身
                      return 判断条件
                })
          some:有一些,只要有一个元素满足,则为true,类似于|| 或操作
              var bool = arr.some(function(val,i,arr){
                      return 判断条件
                })
       2.遍历:拿到数组中的每个元素做相同或相似的操作
           forEach - 直接修改原数组:
               arr.forEach(function(val,i,arr){
                      操作;
                })
           map - 不修改原数组,返回一个新数组:
               var newArr = arr.map(function(val,i,arr){
                      retrun 操作;
                })
       3.过滤和汇总
           过滤:筛选出需要的部分,但和现实不一样,原数组不会变化
               var subArr = arr.filter(function(val,i,arr){
                      retrun 判断条件;
                })
           汇总:var sum = arr.reduce(function(prev,val,i,arr){
                      retrun prev+val;
                })     
        以上6个API是为简化for循环。  
        **ES6箭头函数:专门为了简化一切的匿名回调函数**
          公式:function去掉,()和{}之间添加一个 => ,如果形参只有一个,那么()可以省略,
          如果函数只有一句话,那么{}省略,如果函数体只有一句话并且是return,那么return和{}一起省略。
**二维数组**
    数组的元素,又引用着另一个数组
    何时使用:在一个数组内,再次细分每一个数组
    创建:var arr = [["name","age","height"],["name","age","height"]];
    访问:arr[行下标][列下标];
    特殊:
        面试题:列下标越界,返回undefined;行下标越界,得到一个报错,因为行下标越界其实已经undefined了,undefined没有资格加[]做操作。
    遍历二维数组:
        必然两层循环,外层循环控制行,内层循环控制列。
            for(var r = 0;r<arr.length;r++){
                for(var c=0;c<arr.length;c++){
                    console.log([r][c]);
                }
            }

Srting的概念

什么是字符串:多个字符组成的【只读】字符【数组】(所有的字符串中的API都不会修改原字符串,只会返回一个新的字符串)
和数组的相同点:
    1.字符串中的个数:str.length.
    2.获取字符串中的某个字符:str[i];
    3.遍历字符串
    4.所有数组不修改原数组的API,字符串也可以使用(concat,slice)
和数组的不同点:
    所有的数组的直接修改原数组的API,字符串都不可以使用,比如排序只有数组可以使用,但字符串有着自己专属的API
***引用/对象类型:11个
    *String Number Boolean -> 它们具有包装类型
    *Array *Function Date Math
    *RegExp(正则:验证)
    Error(错误) *Object(面向对象)
***包装类型:专门用于将原始类型的值封装为一个引用类型的对象。
为什么undefinednull不能使用,因为它们没有包装类型。

String的API

    转义字符: \
    作用:将字符串中和程序冲突的字符转为原文。
    包含特殊功能的符号:
    换行:\n; 制表符:\t
    *输出Unicode编码的字符:
        汉字的第一个字:\u4e00;
        汉字的最后一个字:\u9fa5;
    *大小写转换:
        将字符串中每个英文字符统一转为大写或小写
            var 大写 = str.toUpperCase();
            var 小学 = str.tolowerCase();
    *获取字符串中指定位置的字符:
        str.chatAt(i)  === str[i];
    **获取字符串中的指定位置的字符ASCII码:
        var ascii = str.charCodeAt(i);
    ***通过ASCII码转回原文:
        var 原文 = String.fromCharCode(ascii);
    ***检索字符串:检查索引 - 检查下标,获取关键字的下标
        var i = str/arr.indexof("关键字",starti);///从starti位置开始,查找右侧第一个关键字的第一个字符的下标,starti可以省略,默认从0开始查找。
        返回值:找到了,返回的第一个位置的第一个字符下标,
        ***没找到,返回-1,其实我们根本不关心下标为多少,只管下标为不为-1。
        作用:***判断有没有,只要不希望有重复的就用它。
        强调:数组也能用使用此方法,数组这个方法其实是后期才添加上的,原本此方法只有字符串才能使用,ie8及以下此方法不行。
    ***拼接字符串:var newstr = str.concat();
    ***截取字符串:3个
        *var newStr=str/arr.slice(starti,endi+1);
        str.substring(starti,endi+1);//几乎和slice一样,但不支持负数参数。
        str.substr(starti,n);//n代表截取的个数,不必考虑含头不含尾。
    ***替换字符串:
        var newstr=str.replace("固定关键字"/RegExp,"新内容");
    ***去掉开头和结尾的空白字符:
        str.trim();
        str.trimStart()/trimEnd();
    *****切割/分割字符串*****:
        作用:将字符串切割为数组:str <=> arr
        var arr = str.split("自定义切割符");
        特殊:
            1.切割后,切割符就不在了
            2.如果切割符写的是一个空字符串" ",会切散每一个字符。

*扩展

如何使用JS创建页面元素:3步 :深入数据渲染
1.创建空标签: var elem = document.createElement("标签名");
2.为其设置必要的属性和事件
    elem.属性名="属性值";
    elem.onclick事件名=function(){}
3.渲染到DOM树
    父元素.appendChild(elem);

Math对象

专门提供了数学计算的API
强调:math不需要创建,直接使用,由浏览器的JS解释器自动创建。
API:1.取整:3种
        向上取整:超过一点,就会取下一个整数 Math.ceil(num);但小数点位数不能超过15位,超过就失效。
        向下取整:无论超过多少,都会省略小数部分。 Math.floor(num);
        四舍五入:只看小数的第一位。 Math.round(num);
        num.toFixed(d);//d代表保留的有效位数,而且也带有四舍五入
        缺点:返回的结果是一个字符串,建议搭配parsefloat使用。
     2.乘方和开方
         乘方:Math.pow(底数,幂)   === es9提供了简化:底数**幂;
         开方:Math.sqrt(num);//只能开平方
     3.最大值和最小值
         var max/min=Math.max/min(a,b,c,d….);//在你传入的数里面直接找出最大值和最小值。
        问题:默认不支持数组参数
        解决:固定用法:
            Math.max/min.apply(Math,arr);//apply具有打散数组功能。
            或者Math.max/min(…arr);
     4.绝对值:把负数转为正数
        Math.abs(num);//可以是负数
     5.***随机数:Math.random(); // 在0-1之间取一个随机小数
        搭配上parseint,只能取0,不可能取到1,意味着取到最小值,而不是最大值。
        公式:parseInt(Math.random()*(max-min+1)+min);
        强调:只要网页中某一块带有随机功能,底层一定带有随机数。   

Date对象:

 日期对象,提供了可以操作日期和时间的API
 创建:4种
  1.创建当前时间:
    var now=new Date();
  2. *创建一个自定义时间:
    var birth=new Date(“yyyy/MM/dd hh:mm:ss”);
  3. 创建一个自定义时间:
    var birth=new Date(yyyy,MM-1,dd,hh,mm,ss);//修正月份,从0-11月,0代表1月
  4.复制一个日期:
      为什么:日期的所有的API都是直接修改原日期的,无法获得修改之前的日期,
      所以,在执行API之前都要先执行一次复制,然后再操作复制后的日期。
      var end=new Date(start);
 操作:
  两个日期相减,得到一个毫秒差,换算出自己想要的任何一部分 - 日期的本质其实就是保存了一个毫秒数
  创建日期的最后一种方式:var date = new Date(毫秒数);
  **API**
      分量:时间的单位
      年月日星期: FullYear Month Date Day
      时分秒毫秒: Hours Minutes Seconds MiiliSeconds;
      每一个分量都有一对方法getXXX/setXXX
      其中getXXX负责获取一个分量的值
      SetXXX负责设置一个分量的值
     特殊:
        1.取值范围:FullYear – 当前年份的数字  Month – 0~11  Date – 1~31 
        hours – 0~23  Minutes, Seconds 0~59  Day – 0~6,0代表星期天,
        外国人眼里星期天是一周的第一天
        2.任何人都可以设置set ,但Day不可以设置setDay
        3.如果希望对某个分类进行加减操作的话:date.setXXX(date.getXXX()+/-n);
        4.格式化日期为本地字符串:
          date.toLocalString(); 具有兼容性问题,我们一般会选择自己封装一个format函数进
          行格式化,用了此方法会失去:日期的自动进制,以及日期的所有API,但是会得到字符串
          的所有API。
  ** 定时器:**
   1.周期性定时器:每过一段时间就会执行一次,先等再做,会反复执行,需要自己写停止才能停止。
    开启:timer=setInterval(callback,间隔毫秒数);
    停止:clearInterval
   2.一次性定时器:
    开启:timer=setTimeout(callback,间隔毫秒数);
    停止:clearTimeout(timer);

BOM:Browser Object Model 浏览器对象模型

Window对象:

  扮演着两个角色:一个页面和一个window
  1.代替全局对象global,保存着全局变量和全局函数
  2.指代窗口本身
      属性:专门用于获取大小
      *获取浏览器的完整大小:outerWidth/outerHeight;
      *获取浏览器的文档显示区域(就是用户看到的部分)的大小:innerWidth/innerHeight
      *获取屏幕完整大小:screen.width/height;
  打开链接的新方式JS做法:
      1.当前窗口打开,可以后退:open("url","_self");
      2.新窗口打开,可以打开多个:open("url","_blank");
      3.当前窗口打开,只打开一个页面:location.replace("新url")
      使用场景:电商网站,结账后禁止后退。
      4.新窗口打开,不可以后退,只打开一个:open("url","自定义name");
      使用场景:电商网站,只允许用户打开一个结账界面。
  3.a标签的其它用途:
      下载:<a href = "xx.exe/zip/rar/7z"></a>
      打开:<a href = "xx.txt/jpg/png/gif"></a>
  4.打开新窗口/新链接:
      var new = open("url","target","widrh=?,height=?,left=?,top=?");
      特殊:1.如果没有传入第三个参数,那么浏览器和窗口会融入一体,浏览器多大,窗口就多大。
           2.如果传入第三个参数,窗口和浏览器分离开,独立存在。
           3.可以拿个变量保存住此窗口,以后用于其它操作。
  5.关闭窗口:window/new.close();
  6.改变新窗口的大小:new.resizeTo(新宽,新高);
  7.改变新窗口的位置:new.moveTo(新X,新Y);
  8.确认框:var bool = confirm("提示文字");
    输入框:var user = prompt("提示文字");
    警告框:alert("警告文字");
  9.window.onscroll - 滚动事件,一旦滚动就会触发
    *获取滚动条当前的位置:window.scrollY
    *获取页面元素距离顶部有多远:elem.offsetTop/offsetLeft;
  10.*****本地/客户端存储技术:
      cookie:存储大小只有4KB,且只能保存30天,还需要到处切割。
      WebStorage:H5带来的一个新特性:存储大小只有8MB,永久保存,操作简单。
      WebStorage分两类:
          1.sessionStorage:会话级,只要浏览器关闭,数据就会死亡。
          2.localStorage:本地级,只要不清空,它就会永久存在。
          操作:
              1.添加:xxxStorage.属性名="属性值";
              2.删除:xxxStorage.removeItem("属性名");
              3.读取:xxxStorage.属性名;
              4.清空:xxxStorage.clear();
    扩展:
        1.表单提交事件:
               form.onsubmit=function(){
                       操作;
               }
        2.获取时间的毫秒数:date.getTime();