ES5&&ES6

121 阅读13分钟

一、ES5

1、ES5

1.保护对象保护对象的成员(属性和方法)

如何保护:2种

a.四大特性:
    {
        value: 1001, //实际保存值的地方
        writable: true, //开关:控制着这个属性是否可以被修改
        enumerable: true, //开关:控制着这个属性是否可以被for in循环遍历到
        configurable: true //开关:控制着这个属性是否可以被删除
    }
    修改四大特性:
        Object.defineProperties(obj,{
               "属性名":{四大特性},
                ...
        })
b.三个级别
    1)防扩展:禁止给对象添加新属性
          Object.preventExtensions(obj);

    2)密封:禁止给对象添加新属性和删除属性
          Object.seal(obj);

    3)冻结:禁止给对象添加新属性和删除属性以及修改属性
          Object.freeze(obj);
          
    其实保护对象对于我们程序员并不重要:为什么:
        (1)如果你不用面向对象,用的是面向过程,连对象都没有保护个屁
        (2)别人基本不可能知道我们的对象名字叫什么

2、数组的API

1.判断:判断结果一定是一个布尔值

    every - 每一个 - 要求每一个元素都要满足,结果才为true,只要有一个不满足就为false - 类似&&
        语法:arr.every(function(val,i,arr){
                    return 判断条件;
               })

         val - 当前值
         i - 当前值的下标
         arr - 数组本身
   some - 有一些 - 要求每一个元素都不满足,结果才为false,只要有一个满足就为true - 类似||
       语法:
           arr.some(function(val,i,arr){
               return 判断条件;
           })

2.遍历:将数组中的每个元素取出来执行相同 或 相似的操作

 forEach - 直接修改原数组
 arr.forEach(function(val,i,arr){
      操作
 })

 map - 不修改原数组【返回】一个新数组
     arr.map(function(val,i,arr){
     return 操作
 })                       

3.过滤和汇总:

过滤:筛选出自己想要的,但是不会修原数组
     var subArr=arr.filter(function(val,i,arr){
           return 判断条件;
      })

汇总:把数组中的每个元素汇总到一起
     var subArr=arr.reduce(function(prev,val,i,arr){
           return prev+val;
     },基础值);//基础值会和最后的结果在加再一起

以上6个API的底层都是for循环,目的 - 简化for循环,以后能不写for就不写for

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

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

4、严格模式

开启:在你的任意作用域的顶部加上一句话:"use strict";
功能:
   1.禁止给未声明的变量赋值 - 解决全局污染
   2.将静默失败升级为了报错

5、call/apply/bind

  call/apply:临时替换了函数中的this - 借用
  语法:
      函数名.call(借用的对象,实参,...) - 单独传入每一个实参
      函数名.apply(借用的对象,arr) - 只能传入一个实参是一个数组,apply其实会悄悄将数组打散
      强调:
          call/apply,相当于立刻调用函数,立刻执行
          bind:永久替换了函数中的this                         
 3件事:
      1.创建了一个和原函数完全相同功能的新函数
      2.将新函数中的this永久绑定为了指定对象,别人借不走了
      3.将新函数中的部分参数永久固定
 用法:var 新函数=函数名.bind(指定对象,永久实参,...); - 不是立刻执行,需要自己调用
            
 强调:bind绑定的新函数没有办法被call/apply借走                       
 
 推荐:call/apply
 
 固定套路:
     1.Math.max/min.apply(Math,arr);
     2.Object.prototype.toString.call/apply(arr);
     3.类数组转为普通数组:
         var 新变量=Array.prototype.slice.call/apply(类数组对象)

二、ES6

ES6:简化ECMAScript - 语法改变较大

1、模块字符串:``

  `` 可以再字符串中放入变量 - 不需要再做字符串+拼接,在字符串中实现了一个简单的js环境  
  语法:
      `我的名字叫${name}`

2、let关键字:尽量以后【优先】使用let创建变量

  语法:let 变量名=值;
  作用:
      1.禁止声明提前
      2.添加了块级作用域,一个{}就是一个块
      3.记录着当前触发事件的元素的下标
      

3、箭头函数:简化一切的回调函数

 公式:去掉function,在()和{}之间添加=>,如果形参只有一个,省略(),如果函数体只有一句话,省略{}
     如果函数体只有一句话,并且是return,那么{}和return都省略掉
     
 强调:暂时不要将事件简化为箭头函数

4、for...of

 语法:
     for(var v of arr){
            v;//当前值
     }
 缺点:1.不修改原数组
       2.不能遍历hash数组,也不能遍历对象
       

---------------------------------------分割线--------------------------------------------------------------

三、DOM

1、DOM的概念

什么是DOM:
    Document Object Model(文档模型对象)
    将每一个标签/元素/属性/文本/注释,看做是一个DOM节点/元素/对象(提供了一些操作元素的属性和方法)
    
面试题:HTML/XHTML/DHTML/XML
    1.HTML - 网页
    2.XHMTL - 更严格的网页:HTML5->XHTML->HTML4.01
    3.DHTML - 动态网页:D:Dynamic:其实并不是新技术、新概念,是将现有技术的一个整合统称,导致我们在离线版网页也具有动态效果
                DHTML:HTML+CSS+JS(DOM)
    4.XML - 数据格式:淘汰了,现在最流行的数据格式:JSON - javascript Object notation

DOM:原本是可以操作一切结构化文档的HTML和XML,后来为了更方便各类开发者分了31.核心DOM:即可操作HTML又可以XML
    2.HTML DOM:只能操作HTML,API简单,缺点:比如属性部分,只能访问/设置标准属性,不能操作自定义属性
    3.XML DOM:只能操作XML,XML已经淘汰了
    
    开发建议:有限使用HTML DOM,HTML DOM实现不了的在使用核心DOM补充

2、DOM树根:document

 不需要我们创建,一个页面只有一个document对象,由浏览器的js解释器自动创建
 可以通过树根找到每一个DOM节点/元素/对象,提欧共了很多很多的API 
 

3、每个DOM元素都有三大特性

  1.xx.nodeType:描述节点的类型
      document节点:9
      element节点:1
      attribute节点:2
      text节点:3

      以前有用:判断xx是不是一个页面元素,因为以前我们找元素的方法和大家现在不一样

  2.xx.nodeValue:描述属性节点的值,说白了获取属性值
          以前有用:获取一个属性节点的值
  3.xx.nodeName:描述节点的名称(获取标签名) - 判断xx是什么标签

      注意:返回的是一个全大写的标签名 

4、通过关系获取元素

 父:xx.parentNode;
 子:xx.children;
 上一个兄弟:previousElementSibling;
 下一个兄弟:nextElementSibling;
 第一个孩子:xx.firstElementChild;
 最后一个孩子:xx.lastElementChild;                          

5、递归*****

 概念:
     简单来说就删书中有一次调用了函数自己
 何时使用:
     遍历DOM数,专门用于遍历【层级不明确】的情况,既可以遍历层级不同的DOM,也可以遍历层级不明确的数据
 如何使用:2步
   function 函数名(args){
        1.函数体;
                
        2.判断有没有下级,如果有下级,就再次调用此方法,但是传入的实参是直接的下一级
   }
 函数名(实参);
        
 算法:
     深度优先算法!优先遍历房钱节点的子节点,子节点遍历完毕才会跳到兄弟节点
 缺点:
     同时开启大量的函数调用,浪费内存,只有一个情况才使用【遍历层级不明确的】

6、遍历层级不明确的API

缺点:1.专门为遍历层级不明确的DOM准备的,但是不能遍历层级不明确的数据
      2.传入的根元素是不会做操作的
如何:固定用法:2步
      1.var tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT);

      2.反复调用nextNode方法找到下一个元素
            while((node=tw.nextNode())!=null){
                node要干什么
            }

7、API直接找元素

1.单个元素:var elem=document.querySelector("任意css选择器");
            强调:万一选择器匹配到了多个,只会返回第一个
                没找到null
2.多个元素:var elems=document.querySelectorAll("任意css选择器");
            强调:找到了返回集合,没找到返回空集合
            更适合做复杂查找
面试题:getXXX 和 queryXXX的区别?
返回结果不同:
    1.getXXX:获取到返回的是一个动态集合HTMLCollection
    2.queryXXX:获取到返回的是一个静态集合NodeList

动态 vs 静态:
    1.动态集合:根据DOM树的改变,动态集合也会悄悄一起改变,其实会悄悄的再次查找元素
    
        缺点:每次DOM树修改后,都会悄悄的在找一次,效率较低,不支持forEach
    2.静态集合:每次修改DOM树,静态集合是不会发生变化的,只会认准你找的时候的第一次找到的样子
    
        优点:不必反复查找,效率较高,支持forEach
        
总结:
      1.直接找元素:getXXX、queryXXX
      2.通过关系
      3.层级不明确才用递归
                        

8、操作元素:前提是找到元素

1.内容:

     a.elem.innerHTML:获取或设置开始标签到结束标签之间的HTML代码,没有兼容性问题,而且支持识别标签
        获取:elem.innerHTML;
        设置:elem.innerHTML="新内容"

    b.elem.textContent:获取或设置开始标签到结束标签之间的纯文本,具有兼容性问题,不能识别标签
        获取:elem.textContent;
        设置:elem.textContent="新文本"
        老IE:elem.innerText; - 第一次碰到小三上位,原本此方法只有老IE可用,但随着浏览器的更新升级,主流浏览器也支持此属性了
                
    c.input.value; 获取或设置单标签(input)的内容
        获取:input.value;
        设置:input.value="新值"

2.属性

    a.获取属性值:
                核心DOMelem.getAttribute("属性名");
                HTML DOMelem.属性名;

    b.设置属性值:
                核心DOMelem.setAttribute("属性名","属性值");
                HTML DOMelem.属性名="新值";

    c.删除属性值:
                核心DOMelem.removeAttribute("属性名"); - 删除干净
                HTML DOMelem.属性名=""; - 只能删除属性值,但是这个属性节点依然存在,而有的属性,不删干净依然带有功能

    d.判断有没有:垃圾 - 只能判断有没有,不能判断是什么
                核心DOMelem.hasAttribute("属性名");
                HTML DOMelem.属性名!=""

            HTML DOM:虽然简单,但是有两个小缺陷:
                1)class必须写为className - 因为ES6的原因
                2)不能操作自定义属性

3.样式

    1、*内联样式:优先级最高,一定会覆盖掉其他的样式
        仅仅当前元素可用,不会牵一发动全身
        获取样式:elem.style.css属性名
        设置样式:elem.style.css属性名="css属性值" 

9、样式表操作:

    //1.获取你想要操作的样式表
    var sheet=document.styleSheets[1];
    //2.获取样式表中的所有的样式规则
    var rules=sheet.cssRules;
    //3.在所有的样式规则中找到你需要操作那个样式规则
    var rule=rules[45];
    //4.获取或者设置你想要的操作
    console.log(rule.style.background);
    rule.style.background="purple"; 

10、创建元素和渲染DOM树:3步

1.创建空标签:
     var elem=document.createElement("标签名");
2.为其设置必要的属性和事件
     elem.属性名="属性值";
     elem.on事件名=function(){
             操作
     }
3.渲染到DOM树结构上
     *父元素.appendChild(elem); - 将elem追加到父元素里面当最后一个儿子
      父元素.insertBefore(elem,已有子元素) - 将elem追加到父元素里面的已有子元素的前面,不推荐,因为会修改其他元素的下标
      父元素.replaceChild(elem,已有子元素) - 将elem追加到父元素里面的,替换掉已有子元素

11、删除元素:elem.remove();

12、HTML DOM常用对象:【简化】核心DOM

1.image对象:

     图片对象,仅仅只是简化了创建
     创建:var img=new Image();
     注意:不是人人都有构造函数创建方式

2.form对象:查找元素

      查找form元素:var form=document.forms[i];
      查找form元素中的表单控件:var input=form.elements[i];
      *专属事件:form.onsubmit=function(){//提交事件
            阻止提交:return false;
       }

3.select对象:

       属性:
           1.options:获得select下面所有的option,完全等效于xx.children
           2.*selectedIndex:获取选中项的下标 - 唯独select不需要自定义下标

       方法:
           1.*add(option对象);//添加:完全等效于appendChild
           2.remove(i);//删除下标为i的option

       专属事件:select.onchange=function(){//选中项发生改变就会触发
                    
                }
        4.option:仅仅简化了创建
            var opt=new Option(innerHTML,value);

    建议:如果你的option创建好就要放入到select之中:直接一句话完成4个操作
            select.add(new Option("内容","值"))

四、BOM

1、BOM概念:Browser Object Model

浏览器对象模型:专门提供了用于操作浏览器的一些API,没有标准(大部分浏览器还是统一的实现了API,但是老IE和大家不太一样,所以有大量的兼容性问题)

重点:定时器、事件对象event

2、window对象

1.代替了ES中Global,充当全局对象
2.自己带有一些属性和方法:指代当前窗口本身

3、window对象提供的东西

1.网页打开新链接的方式:4种

  目的:提升用户的体验感
  a.替换当前页面,可以后退
      HTML:<a href="url">内容</a>
      JSopen("url","_self");

  b.替换当前页面,禁止后退 - 场景:电商网站,付款后,不允许后退
      history对象:记录着当前窗口的历史记录(打开过的url),只有有了历史过后才能前进后退
      location对象:记录着当前窗口正在打开url,他有一个方法叫做替换,替换是不会产生任何历史的,但是替换url后页面必然会发生改变
      JSlocation.replace("新url")

  c.在新窗口打开,可以打开多个
      HTML:<a href="url" target="_blank">内容</a>
      JSopen("url","_blank");

  d.在新窗口打开,只能打开一个 - 场景:电商网站,只允许用户打开一个付款页面
      HTML:<a href="url" target="自定义name">内容</a>
      JSopen("url","自定义name");

  意思是:每个窗口的底层都有一个名字,如果重新打开相同的name,新打开的会把旧的窗口替换掉

  扩展:a标签的用途?
        a.跳转
        b.锚点
        c.下载:<a href="xx.zip/rar/exe/msi"></a>
        d.打开:<a href="xx.txt/图片后缀"></a>
        e.直接书写javascript:<a href="javascript:js语句;"></a>
        

4、window的属性和方法:

属性:
    获取浏览器的大小:outerWidth/outerHeight;
    获取浏览器的文档显示区域的大小:innerWidth/innerHeight;
    获取屏幕的大小:screen.width/height;

方法:
    1.打开窗口:var newWindow=open("url","target/自定义name","width=,height=,left=,top=");
    
   注意:1)第三个配置参数没有传入时,大小和浏览器一样,并且粘在浏览器上面和浏览器融为一体
         2)如果传了第三个参数,脱离浏览器形成一个小窗口,并且宽高不能设置太小,并且这种小窗口可以自己拿一个变量接住他
    2.关闭窗口:window/newWindow.close();
    3.修改窗口的大小:newWindow.resizeTo(新的宽,新的高)
    4.修改窗口的位置:newWindow.moveTo(新的x,新的y)
        
    扩展:获取鼠标的位置:2步
         1.在事件函数的小括号里面传入一个形参e:自动获得到事件对象event
         2.获取坐标:
              e.screeX/Y - 鼠标相对于屏幕的坐标
              e.clientX/Y - 鼠标相对于文档显示区域的坐标
              e.pageX/Y - 鼠标相对于页面的坐标

    完成鼠标跟随动画:
         1.window/document.onmousemove - 在页面的任何位置移动鼠标都会触发
         2.js的加载速度比图片的加载速度要快,使用加载事件:onload -> 放在onload事件里的代码可以说是最后执行的
         
    定时器:
    何时使用:
        只要是需要等待一段时间在执行的操作都需要用上定时器
        1.周期性定时器:每过一段时间,会执行一次定时器中的操作
                开启:timer=setInterval(callback,间隔毫秒数);
                停止:clearInterval(timer);

        2.一次性定时器:等待一段时间,执行一次定时器中的操作就停止了
                开启:timer=setTimeout(callback,间隔毫秒数);
                停止:clearTimeout(timer);
    注意:一次性和周期性的底层是一样的,甚至可以相互转换,所以到底用哪个无所谓
  面试题:函数 和 循环 和 定时器 都能反复执行,区别在哪里?- 时机不同
         1.函数 - 程序员调用了几次就执行几次,或者 用户触发了几次就执行几次
         2.循环 - 一瞬间就已经执行完毕了
         3.定时器 - 等一段时间做一次