js学习第四周总结

102 阅读12分钟

第一天

一.ES5

一.ES5带来的新特性
    1.保护对象:属性和方法
        1)底层具有四大特性:
            {
                "value":"值"  -->实际保存值的地方
                "writable"true   -->开关:控制着能否被修改
                "enumerable":true  -->开关:控制着可否被for in循环遍历到
                "configurable":true  -->开关:控制着是否可以被删除
                四大特性在需要修改时不需要都写,需要用哪个改变哪个就可以了,但是注意
                    configurable也是一个总开关,一旦它变成了false
                    对象的属性和方法的其他三大特性都不能被再次修改,自己也不可逆转
            }  
          如何修改四大特性:
          Object.definePropertise(对象名,{
              "属性名":{四大特性},
              ...
          })
      2)三个级别:
          第一:防扩展:防止添加:Object.preventExtensitions(需要操作的对象名)
          第二:密封:防止添加、删除:Object.seal(需要操作的对象名)
          第三:冻结:防止添加、删除、修改:Objectfreeeze(需要操作的对象名)
      3)但是这个基本没用
          如果不使用面对对象开发,就保护不了
          而且前辈们都没保护,你更不需要保护
二.数组的新API361.判断:
        every:每一个,理论上完全等效于&&,必须全部满足才能为true,一个不满足就为false
            var bool=arr.every(function(val,i,arr){
                //val当前这个值
                //i当前值的下标
                //arr举例中数组本身
                //以上提供的三个形参不一定全时有用,具体分析具体操作,这里可以有操作
                return 条件
                //上面这个return必须要写
                //如果不写,默认undefined,那么第一个就会为false
            })
      some:有一些,理论上完全等效于||,必须全部不满足才为false,有一个满足就为true
          语法和用法同上,把every换成some即可
   2.遍历:
       forEach:直接修改原数组
           arr.forEach(function(val,i,arr){
               操作
           })
       map:不修改原数组,需要用东西去保存
           var newArr=arr.map(function(val,i,arr){
               return 操作
           })
   3.过滤和汇总:
       filter:过滤,根据条件筛选出需要的部分,用新数组接住
           var subArr=arr.filter(function(cal,i,arr){
               return 过滤条件
           })
       reduce:汇总,把元素汇总到一起
           arr.reduce(function(prve,val,i,arr){
               return prve+val
               //这个prve值是0,是用来最开始进行+的基础值
           },这里可以放一个基础值)//基础值回合arr累加的结果再次相加
   以上6API,都是简化了for循环,而且回调函数在ES6可以简化为箭头函数,不过前提是数组
三.根据父对象设置子对象
    Object.create()
        var 要创建的子对象=Object.create(父对象{
            "属性名":{四大特性}
            ...
            //这样写出来才可以为这个子对象写出属性值
        })
四.严格模式
    开启:在任意作用域的顶部加上一句"use strict"
    功能:1.禁止了给未声明的变量赋值-解决了全局污染
         2.静默失败会升级为报错-一旦报错后面的代码并不执行
五.call、apply、bind:不是自己的方法也可以用
    call/apply【临时】替换了函数中的this--相当于借用
        语法:函数名.call(借用的对象,实参,...)-单独传入每一个实参
              函数名.apply(借用的对象,arr)-只能传入一个数组实参
        强调:这两个相当于立刻调用函数
    bind【永久】替换了函数中的this
        做了3件事:
            1.创建了一个跟原函数功能完全相同的新函数
            2.将新函数中的this永久绑定成了使用bind的这个函数
            3.还可以将新函数中的部分参数永久绑定
        用法:var 新函数=原函数.bind(需要用的对象,永久的实参,...) -这个新函数需要自己对他进行调用
        强调:这样bind出来的函数没办法再被call/apply走
   固定套路:
       1.Math.max/min.apply(Math,arr);
       2.Object.prototype.toString.call/apply(x);
       3.类数组转为普通数组:
           var 普通数组名=Array.prototype.slice.call/apply(类数组对象)
           var 普通数组名=Array.from(类数组对象)

二.ES6

一.模板字符串:可以在字符串中放入变量-不需要再做字符串拼接
    `我的名字叫${变量名}`
二.let 关键字:创建变量的,以后优先使用let而不是var
    let 变量名=值
    作用:
        1.他会禁止声明提前
        2.添加了块级作用域-在使用let的{}就是一个块
        3.它会自动记录当前触发事件的元素的下标
三.箭头函数:简化一切回调函数
    口诀:function删掉,在()和{}中间添加=>,形参如果只有一个省略(),{}里只有一句话省略{},
          如果只有一句话,而且是returnreturn也省略
四.for of循环
    for(var v of arr){
        v;//当前值
    }
    缺点:1.没有下标,无法修改原数组
        2.不能便利hash数组和对象

第二天

一.DOM

一.什么是DOM:Document Object Model(文档对象模型):
    它将页面上每一个标签、元素、属性、文本、注释,都看作一个DOM节点/元素/对象
    (提供了一些操作元素的属性和方法)
    
    HTML/XHTML/DHTML/XML分别是什么
        HTML:网页
        XHTML:更严格的网页
        DHTML:动态的网页
            它是整合现有技术的统称 DHTML=HTML+CSS+JS(dom)
        XML:数据格式
    DOM:原本可以操作一切结构化文档的HTML和XML,后来被细分成了三部分
        1.核心DOM:【非常强】,即可以操作HTML,又可以操作XML
            缺点:API比较繁琐
        2.HTML DOM:只能操作HTML,API非常简单
            缺点:比如属性部分,只能访问/设置标准属性,不能操作自定义属性
        3.XML DOM:只能操作XML,XML已经淘汰了,现在都流行JSON
        优先使用HTML DOM,它解决不了再用核心DOM
二.DOM树:
    树根:document-不需要我们创建
    可以通过树根找到每一个DOM元素/节点/对象
三.DOM元素三大属性:
    1.xx.nodeType-描述了节点的类型
        document节点:9
        element节点:1
        attribute节点:2
        text节点:3
   2.xx.nodeValue-获取元素的属性值的
       因为以前没有getAtrribute,只有getAttributeNode
   3.xx.nodeName-节点的名称-判断xx是什么标签
       但是注意,它得到的结果是一个全大写的标签名
       

二.找元素/节点&找数据

一.通过关系找元素:
    父:xx.parentNode;
    子:xx.children; - 集合,问题:仅仅只能找到儿子,找不到孙子、曾孙...
    第一个儿子:xx.firstElementChild;
    最后一个儿子:xx.lastElementChild;
    前一个兄弟:xx.previousElementSibling;
    后一个兄弟:xx.nextElementSibling;
二.递归:
    简单来说就是在函数中又一次调用了函数自己,但是迟早会停下来
        何时使用:用于遍历【层级不明确】的情况,既可以遍历不明确的DOM,又可以遍历不明确的数据
        如何使用:
            function 函数名(root){
                1.第一层你需要做的操作
                2.等你第一层的操作做完了,判断有没有下一级,有就再次调用,记得实参也要变化    
            }
            函数名(实际的根)
       算法:深度优先!先遍历当前节点的子节点,子节点的子节点这样,遍历完毕再到兄弟节点
       缺点:同时开启大量的函数调用,只有【层级不明确】才会使用
       
       递归 vs 纯循环
            递归:优点:直观易用
                缺点:性能低下
            纯循环:优点:性能高,几乎不占用内存
                缺点:难得批爆
三.遍历层级不明确的API:
    语法:1、创建tw对象
	var tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT);

          2、反复调用tw的nextNode()函数找到每一个元素
	while((node=tw.nextNode())!=null){
		node要干什么操作
	}
    缺点:1、必然跳过根元素,不会对根元素做操作
           2、不可以遍历层级不明确的数据,仅能遍历层级不明确的DOM元素
四.通过API直接找元素:
    1.通过HTML的一些特点去找元素:
        1)id:var elem=document.getElementById("id值")
        2)标签名和class名和Name名:let elems=document/parent.getElementsByTagName/ClassName/Name("标签名/class名")
            name这个属性,input必写,那我们以后input就可以不class了
    2. 通过css选择器获取元素:
        1)单个元素 let elem=document.querySelector("任意css选择器")
            强调:找到多个值返回第一个
                没找到返回null
        2)多个元素 let elem=document.querySelectorAll("任意css选择器")
            强调:找到了返回集合
                没找到返回空集合
    getxxxx和queryxxxx的不同:
        1.getxxxx返回的是动态集合
        2.queryxxxx返回的是静态集合
        动态集合会根据DOM树的改变悄悄的一起变化,每次修改DOM树都会悄悄查找一次
            缺点是性能低却不能使用forEach
        静态集合不会随着DOM树的改变而变化
            优点是复杂查找时简单性能高,而且可以使用forEach

第三天

一.操作元素

一.元素的内容:
    1、*elem.innerHTML:获取或设置开始标签到结束标签之间的HTML代码,可以识别标签
	获取:elem.innerHTML
	设置:elem.innerHTML="新内容"

2、elem.textContent:获取或设置开始标签到结束标签之间的纯文本,具有兼容性问题,不能识别标签
	获取:elem.textContent
	设置:elem.textContent="新文本"
	老IE:elem.innerText - 第一次碰到小三上位,
            原本这个只有老IE可用,但随着各个浏览器的升级发展也支持了,
            老IE没有将就大家 ,反而大家在将就老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
        3)只能操作标准属性,不能操作自定义属性
        3)删除属性把它设置为空有些仍然能生效,没删除干净
三.元素的样式:
    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.创建空元素:
        let elem=document.createElement("标签名")
    2.为这个元素设置必要的属性和事件:
        elem.属性名="";
        elem.on事件名=function(){操作}
    3.将这个元素渲染到树上:
        父元素.appendChild(elem); - 将elem追加到父元素里面当了最后一个儿子
        父元素.insertBefore(elem,已有子元素);  - 将elem追加到父元素里面,并且插入到已有子元素的前面
        父元素.replaceChild(elem,已有子元素)  - 将elem追加到父元素里面,并且替换已有子元素
五.删除元素:elem.remove();
六.HTML DOM提供了一些常用对象:并对这些对象进行了简化,但不是人人都可以简化
    1.image对象:图片对象,仅仅简化了创建
        let img=new Image();
    2.form对象:简化了查找
        查找form元素:var forms=document.forms;
        查找当前这个form元素下面的input:var inps=forms[1].elements;
        专属事件:
            form.onsubmit=function(){//提交事件,只会在提交的一瞬间触发,防止用户输错还能提交
                return false;
            }
    3.select对象:
        属性:1)select.options
             2)select.selectedIndex
        方法:select.add(option)
        专属事件:select.onchange=function()
    4.option对象:
        let opt=new Option("innerHTML","value")
        
     以上两个组合:非常方便的创建
         select.add(new Option("innerHTML","value"))

第三天

BOM

  一.BOM:Browser Object Model(浏览器对象模型)
  二.window对象:扮演者两个角色
      1.在前端:他代替了全局对象global,保存着全局变量和全局函数
          window.变量名
          window.函数名()
          不过window可以省略不写
      2.指当前窗口本身
          一.网页打开新链接的方式
              1)替换当前页面,可以后退
                  HTML:<a/ href="url">内容</a>
                  JS:open("url","_self")
              2)在新窗口打开,可以打开多个
                  HTML:<a/ href="url" target="_blank">内容</a> 
                  JS:open("url","_blank");
              3)在新窗口打开,只能打开一个:使用场景:打开结账页面时
                  HTML:<a/ href="url" target="自定义name">内容</a>
                      窗口的底层其实是有名字的,如果重新打开相同的名字,新打开的窗口会替换掉旧的窗口
                  JS:open("url","自定义name");
             4)替换当前页面,禁止后退:使用场景:结账后不允许后退 
                 history对象:保存着当前窗口打开过的历史记录url,只有产生了窗口历史才能前进后退
                 location对象:保存着当前窗口正在打开的url
                 JS:location.replace("url") 
                     替换网址后页面肯定变化,但是替换并不叫跳转,不会产生任何的历史纪录
             扩展: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.打开新窗口
                     let newW=open("url","自定义name","width=?,height=?,left=?,top=?")
                     //第三个形参没有新窗口就跟原浏览器融为一体
                     //第三个形参如果传入,新窗口就会脱离成为一个独立窗口
                     //第三个形参的数据没有单位
                 2.关闭新老窗口:window/newW.close();  
                 //以下两个操作:仅仅只能对脱离浏览器的新窗口可用
                 3.移动新窗口:newW.moveTo(x,y);
                 4.改变新窗口的大小:newW.resizeTo(new宽,new高);
                 5.定时器:
                     何时使用:只要过一段时间就希望执行的特效或操作,必须使用定时器
                     如何使用:
                         1、周期性:只要不停止会等待时间,反复不断的执行
                             开启:timer=setInterval(callback,间隔毫秒数);
                             停止:clearInterval(timer);
                         2、一次性:等待时间后只会执行一次,就结束
                             开启:timer=setTimeout(callback,间隔毫秒数);
                             停止:clearTimeout(timer);