JavaScript从零开始,第四周学习内容回顾

128 阅读12分钟

ES5

1.保护对象

四大特性:
Object.defineProperties(obj=>{
    "属性名":{
        value:实际保存值
        writable:true/false  //控制这个属性名是否可以修改
        enumerable:true/false  //控制这个属性名是够可以被for in 循环遍历
        configurable:true/false  //控制这个属性名是否可以被删除,这一句是总开关,一旦设置为false,其他特性不允许再修改,一旦设置为false不可逆
    }
})

三个级别:
1.防扩展:禁止给对象添加新属性
Object.preventExtensions(obj);
2.密封:禁止对象添加新属性和删除属性
Object.seal(obj);
3.冻结:禁止给对象添加和删除及修改
Object.freeze(obj);
 保护对象对于我们程序员并没有多大用处

2.数组新API

1.判断:结果为一个布尔值
every:每一个,要求每一个元素都要满足,结果为true只要有一个不满足就为false---类似于&&
语法:
    let bool=arr.every(function(val,i,arr){
        return 判断条件;
    })
    //val  当前值
    //i  当前下标
    // arr  数组本身
    
some:有一些  要求每一个元素都不满足,结果才为false,只要有一个满足就位true ---类似于||
语法:
    let bool=arr.some(function(val,i,arr){
        return  判断条件;
    })
    
 2.遍历:将数组中的每个元素取出来执行相同或者相似的操作
 forEach:遍历数组,直接修改原数组
 语法:
 let forEach(function(val,i,arr){
     直接操作
 })
 map:遍历数组,不修改原数组返回一个新数组
 语法:let newArr=arr.map(function(val,i,arr){
     return 操作结果
 })
 
 
 3.过滤和汇总
 过滤:筛选出自己想要的,但是不会修改原数组
 语法:
     let subArr=arr.filter(function(val,i,arr){
         return  判断条件
     })
 汇总:把数组中的每个元素汇总到一起
 语法:
     let sum=arr.reduce(function(prive,val,i,arr){
         redurn prev+val;
     };基础值)
     //基础值会和最后的结果加在一起
     

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

 语法:
     let 子对象=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.将形函数中的部分参数永久固定
         //不是立刻执行,需要自己调用
 强调:bind绑定的形函数没有办法被 call / apply借走
 推荐使用 call / apply  
 
固定套路:
    1.Math.max / min.apply(Math.arr);
    2.Object.prototype.toString.call / aplly(arr);
    3.类数组转为普通数组.类数组名称
    =Array.prototype.slice.call / apply(类数组);

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

1.模块字符串:可以在字符串中放入变量---不需要再做字符串拼接,在字符串中实现了一个简单的js的环境

语法:
    `我的名字叫${name}`

2.块级作用域:建议优先使用let创建变量

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

3.箭头函数:简化回调函数

公式:去掉function()和{}之间添加=>
      形参如果只有一个,则省略掉()
      函数体如果只有一句话,省略{}
   

4.for...in 循环

 语法:
     for (let v of 数组名){
         v:value:当前值
     }
 缺点:1.不能修改原数组,只能返回新数组
      2.不能遍历hash数组,意味着也不能遍历对象,只能遍历索引数组
      

HTML/XHTML/DHTML/XML分别是什么?

HTML:网页
XHTML:更严格的网页
DHTML:动态的网页;DDynamic:其实并不是新技术,新概念是将现有技术的整合的统称,使我们的网页在离线状态依然具有动态效果
DHTML:HTML+CSS+JS(dom)
XML--数据格式

DOM:原本是可以操作一切结构化文档的HTMLXML后来为了方便各类开发者分为了3个部分
1.核心DOM:既可以操作HTML又可以操作XML
    缺点:API比较繁琐
2.HTML DOM:只能范围/设置标准属性,不能操作自定义属性
3.XML DOM:只能操作XMLXML基本已经淘汰
    建议优先使用HTML DOMHTML DOM满足不了的在用核心DOM
    

DOM树:树根:document ---不需要创建

  一个页面只有一个document对象,由浏览器的js解释器自动生成,可以通过树根找到每一个DOM元素/节点/对象,提供了很多的API
  

每个DOM元素都有三大属性

 1.xx.nadeType:描述节点的类型
     document节点:9
     element节点:1
     attribute节点:2
     text节点:3
 2.xx.nodeVale:属性节点的值,说白了获取属性值
 3.xx.nodeNmae:节点的名称---判断xx是什么标签
     注意:返回的是一个全大写的标签名
 4.通过关系获取元素
  父:xx.parentNode
  子:xx.children--集合只能找到子级儿子不能找到后代
  第一个儿子:xx.firstElementChild
  最后一个儿子:xx.lastElementChild
  前一个兄弟:xx.previousElementSiblind
  后一个兄弟:xx.nextElementSibling
  
 5.递归,函数中又一次调用了函数自己
 何时使用:遍历DOM树,专门用于遍历不明确的情况
 如何使用:2function 函数名(root){
         1.第一层需要做的操作;
         2.判断他有没有下一级,如果有下一级再次调用此函数,只不过传入的实参是他的下一次。
         }
   算法:深度有限,有限遍历当前节点在子节点,子节点遍历完毕后才会跳到兄弟节点;
   缺点:同时开启大量的函数调用,浪费内存,只有一个情况采用:遍历不层级不明确的数组
   
 6.遍历层级不明确的AIPTreeWalker 一个在DOM树上行走的人
   缺陷:专门为遍历层级不明确的DOM准备
   固定公式:
       1.创建tw
let tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT)
       2.反复调用 nextNode方法找到每一个元素
     while(node=tw.nextNode())!=null(){
         node 需要做什么;
     }
    
    
 7.API直接查找元素
    1.通过HTML的一些特点去找元素
        id:let elem=document.getElementById("id");
        tagname / class / name: let elems=document.getElementByTagName / ClassName /Name("标签名/class名")
    2.class选择器获取元素
    单个元素:let elem=document.querySelector("任意css选择器")
        万一选择器匹配到多个,只会返回一个,没找到返回null
    多个元素:lei elems=document.querySelectiorAll("任意css选择器")    
        找到了返回集合,没找到返回空集合,适合做负责寻找
        
问题:get xxx和querySelecto xxx 有什么区别?
    返回结果不同,get返回的是一个动态集合HTMLCol;ection
                querySelecto获取到返回的是一个静态集合NodeList
    动态集合VS静态集合
    1.动态集合根据DOM树的改变,动态集合也一起改变,每一个修改DOM树都会瞧瞧的再次查找DOM。
    缺点:每一次都会悄悄重新查找,效率较低,且不能使用forEach
    2.静态集合:每次修改DOM树,静态集合不会改变只会认准你找到的时候第一次找到的结果。
    优点:每次不会悄悄重新查找,效率较高,可以使用forEach
    
   

元素的内容:

 elem.innerTHML:/="新内容"
 elem.textContent:有兼容性问题
 elem.innerText:纯文本
 elem.value:单标签内容
 

元素的属性

 1.获取
 核心DOM:elem.getAttribute("属性名");
 HTML DOM:elem.属性名;
 
 2.设置
 核心DOM:elem.getAttribute("属性名","属性值");
 HTML DOM:elem.属性名="属性值";
 
 3.删除
 核心DOM:elem.getAttribute("属性名");
 HTML DOM:elem.属性名="";
 
 4.判断:
 if (elem.getAttribute("class")=="d1"){
     使用获取的方式能判断出具体是什么class
 }
 
 5.元素的样式
     1.内联:elem.style.css属性名
             elem.style.css属性名="css属性值"
     2.样式表:
         获取样式表:let sheet=document。styleSheets[1];
         获取样式表中样式规则:let reles=sheet.cssRules;
         数出操作的样式规则:let ryle=rule[30];
         操作:console.log(rule.style.background);
               rule.style.background="purple";

创建元素和渲染DOM数据:3步

 1.创建空标签
 let elem=document.createElement("标签名")
 
 2.为这个空标签添加必要的东西(属性或事件)
 elem.属性名="属性值";
 elem.on事件名=function(){}
 
 3.将内存中创建的元素渲染到DOM树上
 父元素.appendChild(elem);
//将elem最加到父元素里面当了最后一个儿子
  父元素.inserBore(elem,已有子元素);
//将elem追加到父元素里面当儿子,会插在已有子元素的前面下标改变
  父元素.replaceChild(elem.已有子元素);
//追加到父元素里面当儿子,替换已有子元素、

删除元素。elem.remove()

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

1、image对象:仅仅只是简化了创建语句

创建:var img=new Image();//完全等效于var img=document.createElement("img");
注意:不是人人都有构造函数创建方式

2、form对象:简化了查找元素 查找form元素:var form=document.forms 查找form元素中的表单控件:var input=form.elements 专属事件:form.onsubmit=function(){//提交事件,只会在提交的一瞬间触发:防止用户输入错误也能提交 return false;//阻止条件 }

3、*select对象:

  属性:1、*select.options;//得到select下面所有的option,完全等效于xx.children
        2、*select.selectedIndex;//获取到当前选中项的下标 - 只要是做联动就必然会用到

  方法:1、*select.add(option);//完全等效于appendChild
        2select.remove(i);//删除掉下标i的option

专属事件:select.onchange=function(){//只有选中项发生变化的时候才会触发}

4、*option对象:仅仅只是简化了创建语句

    创建:var opt=new Option("innerHTML","value");
建议:HTML DOM别的无所谓,关键selectoption:如果你想要一句话将option创建出来放入到select中:
        select.add(new Option("内容","值"))

BOM:Browser Object Model:

浏览器对象模型:专门用于操作浏览器的API,没有标准(大部分浏览器还是统一的实现了API,除了老IE),BOM使用较少。重点:定时器、事件对象event

window对象介绍:扮演着2个角色

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

window对象提供的东西:

    1、网页打开新链接的方式:41、替换当前页面,可以后退:
	HTML:<a href="url">内容</a>
	JSopen("url","_self");

        2、替换当前页面,禁止后退: - 场景:电商网站:付款后,禁止后退
	history对象:记录着当前窗口的历史记录,只有有了历史才能前进后退
	location对象:记录着当前窗口的正在打开的url,他有一个方法叫做替换,不会产生历史记录
	JSlocation.replace("新url");

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

        4、在新窗口打开,只能开打一个:- 场景:电商网站:只允许用户打开一个付款页面
		HTML:<a href="url" target="自定义name">内容</a>
		  JSopen("url","自定义");
每一个窗口其实底层都有一个名字,如果重新打开相同name,新打开的窗口会将就的窗口给替换掉,_self->自己窗口的名字,_blank->新建一个随机的名字

	总结:
	  1HTML能做的,JS都能做,JS能做的,HTML不一定可以
	  2、不同的跳转方式,可以提升用户的体验感

扩展:a标签的作用:
	1、跳转
	2、锚点
	3、下载:<a href="xx.安装后缀/压缩包后缀">内容</a>
	4、打开:<a href="xx.txt/图片后缀">内容</a>
	5、直接书写javascript:<a href="javascript:js语句;">内容</a> - 可以不用绑定点击事件

window提供的属性和方法:

  属性:获取浏览器的完整大小:outerWidth/Height;
获取到浏览器的文档显示区域的大小:innerWidth/Height; - body的大小获取到屏幕的完整大小:screen.width/height;

方法:1、打开窗口:var newW=open("url","target/自定义","width=,height=,left=,top=");
    
注意:
    1、第三个配置参数没有传入时,大小和浏览器一样,并且粘在浏览器上面的,但是如果有了第三个参数,脱离浏览器
    2、宽高不能设置的太小了
	      2、关闭窗口:window/newW.close();
	      3、修改窗口的大小:newW.resizeTo(newW,newH);
	      4、修改窗口的位置:newW.moveTo(x,y);

扩展:获取鼠标的位置:2步
1、在事件函数中的小括号里传入一个形参e,自动获取到事件对象event
2、获取坐标:
e.screenX/Y - 鼠标相对于屏幕的坐标:鼠标就算在最上面也是70px左右
e.clientX/Y - 鼠标相对于文档显示区域的坐标:网页不管多长多大,始终顶部是0,底部是900多
e.pageX/Y   - 鼠标相对于整个页面的坐标 - 跟随我们的网页变化
完成鼠标跟随动画:
1、window/document.onmousemove - 在页面的任何位置移动鼠标都会触发
2、js的加载速度比图片的加载速度快,使用加载事件:onload

定时器:2种

  1、周期性定时器:每过一段时间,会执行一次定时器中的操作
		开启:timer=setInterval(callback,间隔毫秒数)
		停止:clearInterval(timer);


  2、一次性定时器:等待一段时间,执行一次定时器之中的操作就停止了
		开启:timer=setTimeout(callback,等待毫秒数)
		停止:clearTimeout(timer);

注意:一次性和周期性底层都是一样的,甚至可以相互转换,所以到底用哪个都可以

总结:函数 和 循环 和 定时器 都能反复执行,区别?
	1、函数 - 用户触发绑定事件
	2、循环 - 一瞬间基本就结束了
	3、定时器 - 等一段时间做一次