第六周第一天笔记

1. 复习题

  • 考点:
    • 类的原型如果重新被赋给新的地址,此时里面已经不再有constructor属性;
    • 对象中调用属性时,如果该属性中存在this,那此时this指向该对象;
    • 原型链的考察,如果自己私有属性中找不到目的属性,需要通过原型链向所属类的原型上查找,如果查找到基类的时候,还没有,则返回undefined;
    • undefined与数字进行相加,非法运算,返回NaN;
 <script>
     function Fn(num) {
         this.x=this.y=num;
     }
     Fn.prototype={
         x:20,
         sum:function(){
             console.log(this.x+this.y);
         }//Fn类的原型地址被改变,重新赋值新地址;
     };
     var f=new Fn(10);
     console.log(f.sum===Fn.prototype.sum);//结果true;指向同一个地址,所以严格比较为true;
     f.sum();//结果为20;
     //此时this指向f实例对象;
     Fn.prototype.sum();//结果为NaN;考察原型链,Fn对象上的属性存在x,但是不存在y属性,Fn原型的所属类,为基类,基类原型上也不存在y属性,所以会返回undefined;与数字相加为NaN;
     //此时this指向Fn.prototype对象;
     console.log(f.constructor);//因为已经对Fn.prototype对象进行了重新赋值,添加了新地址,所以新地址中不再有constructor属性;
     //此时f的Fn类的原型上没有了constructor属性,所以还要向它的所属类的原型去找,则找到基类Object上的constructor属性,属性值为基类:"ƒ Object() { [native code] }";
     Fn.prototype.constructor=Fn;//给Fn的原型设置新的constructor属性;
     console.log(f.constructor);//Fn构造函数信息;返回Fn类:"ƒ Fn(num) {this.x=this.y=num;}";
 </script>

2. 数组求平均值

  • 平均值定义:在数组元素中去掉最大值和最小值,剩下的元素求和取平均值;
  • 考点:
    • 数组平均数的定义,去掉最大值,最小值,然后剩下的元素求和取平均值;
    • 数组sort()排序,pop()删除最后一项,shift()删除第一项;
    • join("符号"),将数组用符号连接成字符串;
    • eval("字符串")将字符串作为JS代码执行;
    • 数字.toFixed(位数):将数字四舍五入保留几位小数;
  • 代码:
     <script>
         var ary=[37,27,45,67,87,54,23,45,65,3,56,98,30];
         function average(ary){
             ary.sort(function(a,b){return a-b});
             ary.pop();
             ary.shift();
             var rww=eval(ary.join("+"))/ary.length ;
             return rww.toFixed(3);//将数字结果保留三位小数,四舍五入;
         }
         var res=average(ary);
         console.log(res);
     </script>
    

3. 类数组转数组

  • 原型上的属性方法解读:
    • 每一个类,都有自己的原型,自己原型上的东西,别人不能用
    • 深层去解读一下,原型上的属性或是方法,原型上会有属性名,属性值为函数的定义阶段,当使用原型上的某个属性时,获得是函数定义地址,所以需要加(),就是执行函数,也称为方法;
    • 原型上的属性在定义阶段,函数里面会进行很多设置,设置是针对谁?针对的是实例对象,也就是this,函数在定义的时候,就默认将实例对象传进去了,一切的操作都是对this实例对象进行开刀,即进行其他的操作;
    • 数组类Array的原型上存在系统属性:slice,concat等,所对应的属性值为一个定义函数,里面所设置的都是对象实例this,要想不属于数组类去享受这个方法,就可以将this改变为那个类;
    • 类数组具有数组的特征,属性和方法样式一样,但是不属于数组类,不能去获得数组类原型上的属性方法;所以就需要通过call,apply,bind这些方法来将类数组对象变为数组类原型上属性方法中的this实例对象;这样就可以享受封装的方法了;
  • 类数组转化为数组的方法:
    • 代码:var ary1=Array.prototype.slice.call("类数组");
      • 实质:就是获取数组类原型上的slice属性,将其实例对象this改为类数组对象;
      • 只要能通过原型链获取数组类原型上的slice属性就行,所以也可写成var ary1=[].slice.call("类数组")
    • 此时ary1就是类数组转化为的真正数组,属于数组类Array,同时享用数组类原型上的属性方法;
    • 方法解读:利用类数组arguments来解读类数组转数组的方法;
      <script>
             var ary=[12,3,4,54,56,34,55];
             var ary1=ary.slice();//结果克隆ary数组,说明slice()方法在克隆时,可以不传参;
            /* var ary1=ary.slice(0);//效果一样,slice()方法在克隆时,可以传入实参0;*/
             console.log(ary1);
             function mas() {
                 //arguments就接受了所有的实参,实参作为元素形成一个类数组;
                 var res=Array.prototype.slice.call(arguments);//实现类数组转数组;
                 console.log(res);
                /* var res=Array.prototype.slice.call(arguments,0);//对应上面的传入0的实参;*/
                 //此时res就是一个真正的数组,属于数组类Array,同时享用数组类上面的属性方法;
                 var ree=res.concat(45);
                 console.log(ree);
             }
             mas.apply(null,ary);//apply作用,就是将数组中的元素作为实参传入函数中;
         </script>
    
  • 类数组有两种
  • 函数获取实参的arguments,它就是一个类数组,形似数组,但不属于数组类Array;
    • 将类数组转化为数组的方法:var ary1=Array.prototype.slice.call(arguments),获得ary1就是一个数组,就可以使用数组类上的所有方法;
    • 该方法兼容性良好,IE浏览器也支持;
  • 元素集合:htmlCollection;
    • 方法代码:
      <script>
          var adiv=document.getElementsByTagName("div");//元素集合类数组;
          var ary=Array.prototype.slice.call(adiv);
          console.log(ary instanceof Array)//结果为true,但是IE7浏览器不支持,会报错;
          console.log(ary);
      </script>
    
    • 兼容性不好,IE8及其以下浏览器不支持,会报错;
    • 不兼容的时候,新建一个空数组,将类数组中的各个元素遍历放在空数组中,形成的新数组就可以用数组类上的属性和方法;
  • 类数组转数组的封装方法,在不同的浏览器中都适用;
     <script>
         //需求:将类数组转化为数组,注意兼容性问题
         //参数:类数组(arguments,htmlCollection);返回值:数组
         function makeArray(arg){
             try{//当浏览器兼容的时候,执行下面代码不报错,则不会执行catch语句;
                 return Array.prototype.slice.call(arg);
             }catch(e){//当浏览器不兼容的时候,会报错,然后执行catch语句
                 var ary=[];
                 for(var i=0; i<arg.length; i++){
                     ary.push(arg[i]);
                 }
                 return ary;
             }
         }
     </script>
    

4. 浏览器的异常捕获

  • 浏览器异常捕获
    • 代码:try{...}catch(e){..}....finally{..},完整写法;
    • 但是平常用try{...}catch(e){..}...,finally可写可不写,不常用;
    • 在catch中
      + 代码:console.error(e)指的是打印出红色的报错代码;
      + 代码:console.log(e)指的是打印出黑色的报错代码;两者报错代码相同;
      + 代码:throw new Error(e)指的是阻断下面代码执行,将错误抛出;
    • 目的:处理浏览器的不兼容问题,有的浏览器下会报错;在执行try中的语句时,若不报错,不执行catch中的语句;若报错,然后执行catch中的语句;
     <script>
         //浏览器异常捕获;
         var a=2222;
         //当a存在时,就会走try里面的语句,然后还会走finally中的语句;
         //当a不存在时,会报错,走catch里面的语句打印出错误代码,但是不会阻断程序执行,finally会继续执行;
         //无论走try还是走catch都会走finally;所以可写可不写;
         try{
             alert(a);
         }catch(e){
            console.error(e)//打印出来是红色的代码;
            //console.log(e)//打印出来的是黑色的代码;两者代码相同
            //throw new Error(e);//将错误抛出;阻断外面代码alert(333)执行,但finally中的代码依然执行,
         }finally {
             alert(1111);//此时无论走try还是走catch都会走finally;所以可写可不写;
             //添加throw new Error(e)都不能影响finally中的代码执行;
         }
         alert(333);//无论执行try还是执行catch,此处代码都执行;但是如果走catch的时候,catch中添加throw new Error(e)语句,那么此处的代码就被阻断;
     </script>
    
    • 使用场景,只要有报错的情况,建议使用try...catch..;

5. jsonParse封装

  • window为Window的实例对象,而JSON为window的私有属性;
  • JSON为系统window的属性,JSON上有两个属性方法,parse()和stringify()
    • JSON.parse(strJson):把JSON格式的字符串strJson转化为JSON格式的对象;
    • JSON.stringify(objJson):把JSON格式的对象转化为JSON格式的字符串;
    • JSON格式对象与普通对象的区别是:JSON格式的对象中的属性名一定用双引号"";属性值如果是数字可以不加引号;
    • 注意:兼容性问题:在IE7下,window的不存在JSON属性;所以window.JSON返回的是undefined;
  <script>
      var obj={name:"guobin",age:8};//普通对象
      var objJson1={"name":"guogin","age":26};//JSON
      //JSON中属性名,属性值都用双引号,如果是数字可以不加;
      var objJson=[{"name":"guogin","age":26},{"name":"guogin1","age":26},{"name":"guogin2","age":26},];//数组对象;
      console.log(objJson);
      var mass=JSON.stringify(objJson);//转化为字符串;
      console.log(mass);
      var mss=JSON.parse(mass);//转化为对象;
      /*//JSON在IE浏览器中不支持;
      //解决方法:用eval();
      var mss1=eval("("+mass+")");*/
      console.log(mss);
  </script>

6. 工具库封装

  • 考点:
    • utils工具库是新建的一个JS文件,用于调用属性方法;
    • 里面格式使用自执行函数,避免添加全局变量
    • 代码中添加完键值对后,在上面输入/**然后按回车键,就会自动添加注释;
    • 两种方法的对比,体现了try..catch..方法与if..else..方法的使用情景
    • try..catch..方法用在不同浏览器的兼容性问题中,即有些浏览器支持,有些浏览器会报错;
      • 在运行时,在支持的浏览器下执行try命令,在不支持的浏览器下执行catch命令;
    • if...else..方法,用在不同浏览器的兼容性问题中,即有些浏览器支持,有些浏览器不支持某一属性,会返回undefined,但不会报错;
      • 判断条件一般为是否存在该属性,如果存在就执行if语句,如果不支持就执行else语句;
  <script>
    //utils工具库
    //自执行函数的目的是形成一个私有的作用域,避免添加全局属性;
    //里面return返回的是一个对象;
    var utils=(function () {
        return {
            /**
             * 类数组转化为数组的封装方法
             * @param arg(arguments,htmlCollection)
             * @returns {Array}(返回数组)
             */
            makeArray:function(arg){
                var ary=[];
                //此时用try..catch..方法,是因为htmlCollection类数组,在IE浏览器中不能修改this,会报错;
                try{
                    ary=Array.prototype.slice.call(arg);
                }catch(e){
                    for(var i=0; i<arg.length; i++){
                        ary.push(arg[i]);
                    }
                }
                return ary;
            },
            /**
             * 把JSON格式的字符串转化为JSON格式的对象
             * @param strJson
             * @returns {Object}
             */
            jsonParse:function (strJson) {
                //此时用if..else..,不用try..catch..的原因是:在IE7中window不存在JSON属性,所以返回的是undefined,不会报错,只有当报错的时候,才会只用try..catch..;
                if(window.JSON){//判断条件可以是"JSON" in window;属性从属判断;
                    return JSON.parse(strJson);
                }else{
                    return eval("("+strJson+")");//eval()的坏处会存在注入攻击;
                }
                //三目写法:return window.JSON ? JSON.parse(strJson) : eval("("+strJson+")");
            }
        }
    })();
  </script>

7.sort排序深入解读

  • sort排序
    • 数组元素为数字,让其从小到大依次排序
    • 代码:
      ary.sort(funtion (a,b){
                  return a-b;//可以写成(b-a)*-1;
              })
    
    • 数组元素为数字,让其从大到小依次排序
      • 代码:
        ary.sort(funtion (a,b){
                    return b-a;//可以写成(a-b)*-1;
                })
      
    • 数组元素为数字加字符串,通过其中数字进行从小到大排序;利用"parseInt()"或"parseFloat()"方法转换;
      • 注意:parseInt(m)与parseFloat(m)两个非严格转换,当m为"12meihao"时,结果都为12;但是当m为"meihao12"时,结果为NaN;所见数字必须在前面才能进行转换,在后面转换失败;
      <script>
          var ary=["2成龙","4胡歌","1李连杰","5阿祖","3刘亦菲"];
          //利用sort()对数组进行排序
          //需求1:通过每个字符串中的数字进行排序;
          //知识点:字符串转化为数字的非严格转换parseInt()或parseFloat()
          ary.sort(function (a,b) {
              a=parseInt(a);
              b=parseInt(b);
              return a-b;
          });
          console.log(ary);//结果为["1李连杰", "2成龙", "3刘亦菲", "4胡歌", "5阿祖"];
      </script>
    
  • DOM映射:html页面中的DOM结构,跟通过JS获取到的元素集合htmlCollection之间,存在一一对应的关系
    • 利用appendChild()方法,其实目的是剪切作用,把排完序的元素结合,插入到oul元素节点的最后一个子节点,此时DOM结构中,相对应的元素,会剪切到最后一位;
    • 改变DOM结构方法:1)appendChild();2)insertBefore();3)removeChild();4)replaceChild();
    • 实例需求1:利用sort()方法,将DOM结构中的每个li元素,通过内容中的数字进行从小到大的顺序排列;
      //需求:利用sort()方法,将DOM结构中的每个li元素,通过内容中的数字进行从小到大的顺序排列;
      <body>
      <ul>
          <li>1我是列表</li>
          <li>3我是列表</li>
          <li>2我是列表</li>
          <li>4我是列表</li>
      </ul>
      <script src="utils.js"></script>
      <script>
          var ali=document.getElementsByTagName("li");
          var oul=document.getElementsByTagName("ul")[0];
          //把类数组,转化为数组
          var ary=utils.makeArray(ali);
          //利用sort()进行列表排序,按照里面的内容数字排列;
          ary.sort(function (a,b) {
              a=parseInt(a.innerHTML);
              b=parseInt(b.innerHTML);
              return a-b;
          });
          //改变DOM页面结构,方法:appendChild(),insertBefore()
          for(var i=0; i<ary.length; i++){
              oul.appendChild(ary[i]);
          }
      </script>
    
    • 实例需求2:利用sort()方法,将DOM结构中的每个li元素,通过内容文字拼音的首字母进行从a-z顺序排序,利用localeCompare()方法;
     <body>
     <ul>
         <li>李连杰</li>
         <li>成龙</li>
         <li>甄子丹</li>
         <li>杨紫琼</li>
     </ul>
     <script src="utils.js"></script>
     <script>
         var ali=document.getElementsByTagName("li");
         var oul=document.getElementsByTagName("ul")[0];
         //把类数组,转化为数组
         var ary=utils.makeArray(ali);
         //利用sort()进行列表排序,按照里面的内容数字排列;
         ary.sort(function (a,b) {
             a=a.innerHTML;
             b=b.innerHTML;
             return a.localeCompare(b);//按照汉字拼音的首字母的从a-z进行排序
             //return a.localeCompare(b)*-1;//按照汉字拼音的首字母的从z-a进行排序
             //return b.localeCompare(a);//也可写成这种形式,按照汉字拼音的首字母的从z-a进行排序
         });
         //改变DOM页面结构,方法:appendChild(),insertBefore()
         for(var i=0; i<ary.length; i++){
             oul.appendChild(ary[i]);
         }
     </script>
    
    • 注意:localeCompare()方法运用不准确;

8. 插入页面的几种方式

  • 字符串拼接;最简单,最常用,字符串插入页面用innerHTML;
    • 问题:如果页面中以前的元素在添加之前身上有事件,当重新进行字符串拼接后,重新再插入页面,那么他们以前身上的事件就都不存在了;
  <body>
  <div><span>姓名</span><span>年龄</span></div>
  <script>
      var ary=[
          {"name":"guobin","age":26},
          {"name":"guoyang","age":19},
          {"name":"guodan","age":18},
          {"name":"guoyao","age":14},
          {"name":"guorunze","age":2}
      ];
      //1.字符串拼接;最简单,最常用,字符串插入页面用,innerHTML;
      //问题:如果页面中在添加以前的元素身上有事件,当重新进行字符串拼接后,重新再插入页面,那么他们以前身上的时间就都不存在了;
      var aDiv=document.getElementsByTagName("div");
      aDiv[0].onmouseover=function () {
         this.style.backgroundColor="pink";
      };
      aDiv[0].onmouseout=function () {
          this.style.backgroundColor="";
      };
      var str="";
      for(var i=0; i<ary.length; i++){
          var cur=ary[i];
          str+="<div><span>"+cur.name+"</span><span>"+cur.age+"</span></div>"
      }
      //2.插入到页面中
      document.body.innerHTML+=str;//document.body指的是body元素节点;
     //此代码意思是,将原来的字符串从页面上拿出来,然后与新的字符串进行拼接,然后再重新插入页面中;此时原来设置的事件都不存在了;必须重新设置;
  </script>
  </body>
  • DOM动态插入:新建元素及内容,每建一个就插入一个到页面
    • 问题:每新建一个odiv就需要向页面中插入一次,如果数组中对象个数很多,就会频繁插入页面,会产生影响;
  <script>
      //2.DOM动态插入
      for(var i=0; i<ary.length; i++){
          var cur=ary[i];
          var odiv=document.createElement("div");
          for(var attr in cur){
              var ospan=document.createElement("span");
              ospan.innerHTML=cur[attr];
              odiv.appendChild(ospan);
          }
          document.body.appendChild(odiv);
      }
  </script>
  • 文档碎片:对页面的优化,简化DOM操作,就是把所有创建的odiv先放在文档碎片中,最后一起插入到页面中,当插入完后,将其释放,达到性能优化的目的;
    • 优点:创建文档碎片,将每次新建的odiv,放在文档碎片中,最后新建完毕,统一插入到页面中,减少频繁操作;当插入完毕后,对文档碎片清除,性能优化;
    • 创建文档碎片:var frg=document.createDocumentFragment();
    • 清除内存:frg=null;
  <body>
  <div><span>姓名</span><span>年龄</span></div>
  <script src="data.js"></script>
  <script>
      var frg=document.createDocumentFragment();//新建一个文档碎片,用于接收每次创建的odiv元素;
      for(var i=0; i<ary.length; i++){
          var cur=ary[i];
          var odiv=document.createElement("div");
          for(var attr in cur){
              var ospan=document.createElement("span");
              ospan.innerHTML=cur[attr];
              odiv.appendChild(ospan);
          }
          frg.appendChild(odiv);
      }
      document.body.appendChild(frg);//将文档碎片插入到body元素中;
      frg=null;//赋值null,将文档碎片删除,性能优化;
  </script>
  </body>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容

  • JS基础 页面由三部分组成:html:超文本标记语言,负责页面结构css:层叠样式表,负责页面样式js:轻量级的脚...
    小贤笔记阅读 590评论 0 5
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,039评论 0 3
  • 第一章1,什么叫程序:程序就是计算机按照人类完成事物的步骤和逻辑,通过计算机命令来逐步执行最终实现目标的一种机器语...
    悟名先生阅读 936评论 0 4
  • 手势总结https://www.jianshu.com/p/21bb5ba47660 https://www.ji...
    Alan龙马阅读 55评论 0 0
  • 立秋过后,虽说暑气消退了许多,可室内依旧有些闷热,门外的绿荫下倒是清凉了许多。 “走!儿子,散步去。”傍晚,我看着...
    曰日如歌阅读 264评论 5 7