js第四周

72 阅读11分钟

保护对象:

    1、底层具有四大特征:
            "value":"" - 真正实际保存值得地方
            "writable":true, - 开关:控制着是否可以被修改
            "enumerable":true, - 开关:控制着是否可以被for in循环遍历
            "configurable":true - 开关:控制着是否可以被删除,总开关
            
     如何修改四大特征:
             Object.definePriperties(对象名,{
                 "属性名":{四大特征},
                 .......
             })
             
    2、三个级别:
            1、防扩展:防止添加:Object.preventExtensions(obj);
            2、密封:防止添加、删除:Obiect.seal(obj);
            3、冻结:防止添加、删除、修改:Object.freeze(obj);
            

数组的API:

   1、判断:
           every:每一个,理论完全等效于&&,必须全部满足结果才为true,只要有一个不满足,结果就位false
           var bool=arr.every(function(val,i,arr){
               //var - 当前值
               //i - 当前值得下标
               //arr - 数组本身
               return条件;//必须写
           })
           
           some:有一些,理论完全等效于||,必须全部不满足结果才为false,只要一个满足,结果就为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){
                     return操作;
                 })
                 
 3、过滤和汇总:
         过滤:根据你的条件,筛选出你需要的部分,但是不会修改原数组
         var subArr=arr.filte(function(prev,val,i,arr){
             return prev+val;
         },基础值);
         

Object.create(): 根据父对象创建子对象,设置好继承

        var 子对象=Obiect.create(父对象,{
                "属性名":{四大特征},
                ...
        });
        

严格模式:

   开启:在你的任何作用域的顶部加上一句话:"use strict"
   功能:1、禁止了给未声明的变量赋值 - 解决全局污染
        2、静默失败升级为了错误,一旦报错后续代码就不再执行了
        

call、apply、bind: 不是自己的方法也可以用

    call/apply:临时替换了函数中的this - 借用
            语法:函数名.call(借用的对象,实参,...)//单独传入每一个实参
            函数名.apply(借用的对象,arr)//只能传入一个实参,要求是一个数组实参
            强调:call、apply,相当于立刻调用函数,立刻执行
            
    bind:永久替换了函数中的this
        1、创建了一个和原函数功能完全相同的新函数
        2、讲新函数中的this永久绑定为了指定对象
        3、将新函数中的部分参数永久固定
        用法:var 新函数=原函数.bind(指定对象,永久实参,...);- 不是立刻执行的,需要执行的时候调用
        强调:bind绑定的新函数没有办法被call、apply借走
        
  固定套路:
          1Math.max/min.apply(Math,arr);
          2Object.prototype.toString.call/apply(x);
          3、类数组转为普通数组:
                  var 普通数组=Array.prototype.slice.call/apply(类数组对象);
                  ES5还给出了一种方案:var 普通数组=Arrar,from(类数组对象)
                  

ES6:

1、模版字符串:可以在字符串中放入变量 - 不需要再做字符串拼接,在字符串中实现一个简单的js操作
`我的名字叫${name}`
2let关键字:创建变量
    let 变量名=值;
    作用:
        1、禁止声明提前
        2、添加了块级作用域 - 一个{}就是一个块
        3、记录着当前触发事件的元素的下标
        
3、箭头函数:简化一切回调函数
        口诀:function删掉,在()和{}之间添加=>,形参如果只有一个,可以省略小括号,函数体只有一句话,删除{},函数体只有一句话并且是return,{}和return都删除
        
4for of循环:
    for(var v of arr){
           v;//当前值
     }
    缺点:1、因为没有下标,无法修改原数组
          2、无法遍历hash数组,也不能遍历对象
          

DOM: 什么是DOM:Document Object Model(文档对象模型),将每一个标签、元素、属性、文本、注释,都看作一个DOM节点、元素、对象(提供了一些操作元素的属性哈方法)

 面试题:HTML/XHTML/DHTML/XML分别是什么?
         1HTML - 网页
         2、XHTML - 更严格的网页
         3、DHTML - 动态的网页
         4、XML - 数据格式化
         
 DOM:原本是可以操作一切结构化文档的HTML和XML,后来为了方便各类开发者细分为了3部分
         1、核心DOM:无敌的,既可以操作HTML,又可以操作XML
         缺点:API比较繁琐
         2HTML DOM:只能操作HTML
         优点:API非常简单
         缺点:比如属性部分,只能访问、设置标准属性,不能操作自定义属性
         3、XMLDOM:只能操作XML
         开发建议:优先使用HTMLDOM,HTMLDOM满足不了的操作再用核心DOM进行补充
         

DOM树:树根:document - 不需要我们创建,一个页面只有一个document对象,由js解释器自动创建

每个DOM元素都有三大属性:

        1、xx.nodeType - 描述节点的类型
                document节点:9
                element节点:1
                attribute节点:2
                text节点3
                
        2、xx.nodeValue - 获取元素的属性值得
        3、xx.nodeName:节点的名称 - 判断xx是什么标签
        注意:返回的是一个全大写的标签名
        
        

通过关系获取元素:

     父:xx.parentNode;
     子:xx.children; - 集合,问题:仅仅只能找到儿子
     第一个儿子:xx.firstElementChild;
     最后一个儿子:xx.lastELementChild;
     前一个兄弟:xx.previousElementSiblibling;
     后一个兄弟:xx.nextElementSibiling;
     

递归:简单来说就是函数中,有一次调用函数自己,迟早有一天也会停下来

    何时使用:遍历DOM树,专门用于层级不明确的情况,既可以遍历层级不明确的DOM,又可以遍历层级不明确的数据
    如何使用:
        function 函数名(root){
            1、第一层你要做什么操作直接做
            2、判断他有没有下一级,如果有下一级再次调用此函数,但是传入的实参是下一级的东西
        }
       函数名(实际的根);
       
   算法:深度优先,优先遍历当前节点的子节点,子节点遍历完毕后才会跳到兄弟节点
   缺点:同时开启大量的函数调用,消耗大量的内存,只有一个情况下才会使用:遍历层级不明确
   

遍历层级不明确的API:

    语法:
        1、创建tw对象
            var tw=document.create TreeWalker(根元素,NodeFilter.SHOW_ELEMENT);
            
        2、反复调用tw的nexrNode()函数找到每一个元素
        while((node=tw.nextNode())!=null){
            node要做什么操作
        }
        缺点:1、必然跳过根元素,不会对根元素做操作
             2、不可以遍历层级不明确的数据,仅能遍历层级不明确的DOM元素
             

API直接找到元素:

    1、通过HTML的一些特点去找元素
        1、id:var elem=document.getElementById("id值");
        2、标签名和class名和Name名:
        var elems=document/parent.getElementsByTagName/ClassName/Name("标签名、class")
        name这个属性,input必写,那我们以后input就可以不用class2、通过class选择器获取元素:
            1、单个元素:var elem=document.querySelector("任意css选择器");
            强调:1、万一选择器匹配到多个,只会返回第一个
                  2、没找到null
                  
           2、多个元素:
           var elems=document.quereySelectorAll("任意css选择器")
           强调:找到了返回集合,没找到返回空集合,更适合做复杂查找
           

面试题:

    getXXX和queryXXX的区别?返回结果不同?
        1、getXXX:返回的是一个动态集合HTMLCollection
        2query:返回的是一个静态集合NOdeList
        
    动态集合:根据DOM树的改变,悄悄的一起跟着变化,每一次修改DOM,都会悄悄的查找页面元素,缺点:性能低,而且不能使用forEach
    静态集合:根据DOM树的改变,不会一起变化,只会认准当时找的的数据,优点:复杂查找时简单、性能高、使用forEach
    
    

操作元素:

    1、元素的内容:
            1、elem.innerHTML:获取或设置开始标签到结束标签之间的HTML代码,可以识别标签
            获取:elem.innerHTML
            设置:elem.innerHTML="新内容"
            
            2、elem.textContent:获取或设置开始标签到结束标签之间的纯文本,具有兼容问题不能识别标签
            获取:elem.textContent
            设置:elem.textContent="新文本"
            老IE:elem.innerText - 原本这个只有老IE可用,后来随着各个浏览器的升级也都支持使用了
            
            3、input.value:获取或设置input值
            获取:input.value
            设置:input.value="新值"
            

元素的属性:

1、获取属性值
    核心DOM:elem.getAttribute("属性名");
    
    HTML DOM:elem.属性名;
    
2、设置属性值:
    核心DOM:elem.setAttribute("属性名","属性值");
    
    HTML DOM:elem.属性名="新值";
    
3、删除属性值:
    核心DOM:elem.removeAttribute("属性名");
    
    HTML DOM:elem.属性名=""

4、判断有没有:只能判断有没有,不能判断具体是什么
    核心DOM:elem.hasAttribute("属性名");
    
    HTML DOM:elem.属性名!=“”;
    
强调:HTML DOM确实简单,但是需要注意:
            1、class必须写为className
            2、只能操作标准属性,不能操作自定义属性
            3、删除属性时,删不干净,有的属性删不干净依然具有功能:比如:href没有属性会有默认刷新功能
            

元素的样式:

    1、内联样式:优先级最高,一定会覆盖其它的样式
        仅仅当前元素可用,不会牵一发动全身
       获取:elem.style.css属性名;
       设置:elem.style.css属性名=“css属性值”;
       唯一的小缺陷:获取样式时,只能获取到内联的样式
       
    2、样式表:
            //1、获取你想要操作的样式表
            var sheet=document.styleSheets[i];
            //2、获取所有的样式规则
            var rules=sheet.cssRules;
            //3、所有的规则中挑选出你需要的操作的规则
            var rule=rules[i];
            //4、做获取或设置
            console.log(rule.style.width);
            rule.style.width="100px"
            

创建元素并且渲染DOM树:

    1、创建空元素:
        var elem=document.createElement("标签名");
        
    2、为这个空标签设置必须要的属性和事件
        elem.属性名="属性名";
        elem.on事件名=function(){操作}
        
    3、将这个元素渲染到DOM树上
        父元素,appendChild(elem); - 将elem追加到父元素里面当最后一个儿子
        父元素.insertBefore(elem,已有子元素); - 将elem追加到父元素里面,并且插入到已有子元素的前面
        父元素.replaceChild(elem,已有子元素); - 将elem追加到父元素里面,并且替换已有子元素
        
    删除元素:elem.remove();
    

HTML DOM提供了一些常用对象:并且对这些对象进行了简化,但是不是人人都可以简化

1、image对象:图片对象,仅仅只是简化了创建
    创建:var img=new Image();
    注意:不是人人都有构造函数创建方式
    
2、form对象:简化了表单对象,简化的是查找:
    查找form元素:var forms=document.forms;
    查找当前这个form元素下面的input:var inps=form[1].elementsl
    专属事件:form.onsubmit=function(){
        return flase;
    }
    
3select对象:
        属性:1select.options;//得到select下面的所有的option,完全等效于xx.children
            2select.selectedIndex;//获取到当前选中项的下标
        方法:select.add(option);//完全等效于appendChild
        专属事件:select.onchange=function(){
            选中项发生改变的时候才会触发
        }
        
 4、option对象:仅仅简化了创建
     var opt=new Option("innerHTML","value");
     
    一句话完成四个操作:
        select.add(new Option("innerHTML","value"));
        

window对象:

    1、在前端、浏览器端,他代替了全局对象global,保存着全局变量和全局函数
        window.变量名;
        window.函数名(); - 只不过window可以省略不写
        
    2、指代当前窗口本身
        目的:优化用户的体验感,多为用户考虑
        1、网页打开新链接的方式
            1、替换当前页面,可后退
                HTML:<a href="url">内容</a>
                
                JS:open("url","_seif");
                
            2、替换当前页面,禁止后退:使用场景:结账后不允许后退
            history对象:保存着当前窗口打开过的历史记录URL,只有产生了窗口历史才能前进后退
            location对象:保存着当前窗口正在打开的URL
            
            JS:location.replace("url") - 替换网址后页面肯定会发生变化,但是替换并不叫跳转,不会产生任何历史记录
            
            3、在新窗口打开,可以打开多个
            HTML:<a href="url" target="自定义name">内容</a>
            JS:open("url","_blank");
            
            4、在新窗口打开,只能打开一个:使用场景:打开结账页面时
            HTML:<a href="url" target="自定义name">内容</a>
            JS:open("url","自定义name");
            
      扩展:a标签的其他用处:
              1、跳转
              2、锚点
              3、下载:<a href="xx.exe/zip/rar">下载</a>
              4、打开:<a href="xx.txt/jpg...">图片、文本</a>
              5、直接执行js操作:<a href="javaScript.js代码;"></a>
              

window窗口的属性和方法:

    属性:
        获取大小:
                1、获取浏览器的完整的大小:outerWidth/Height
                2、获取浏览器的文档显示区域的大小:innerWidth/Height
                3、获取完整屏幕的大小:screen,width/height
                
   方法:
       1、打开新窗口:var newW=open("url","自定义name","width=?,height=?,left=?,top=?");
       //第三个参数如果没有传入,那么新窗口大小和位置会与浏览器融为一体
       //第三个参数如果传入,新窗口会脱离浏览器独立成为一个小窗口
       2、关闭新老窗口:window/newW.close();
       //以下两个操作:仅仅只能对脱离浏览器的新窗口可用
       3、移动新窗口:newW.moveTo(x,y);
       4、改变新窗口的大小:newW.resizeTo(new宽,new高);
       
    扩展:获取鼠标的位置:
            1、获取事件对象event:在事件函数中传入一个形参e即可,自动接收event对象
            2、获取鼠标的位置:
                    1、鼠标相对于屏幕的位置:e.screenX/Y
                    2、鼠标相对于文档显示区域的位置:e.clientX/Y
                    3、鼠标相对于网页的位置:e.pageX/Y