JS学习总结

152 阅读18分钟

JavaScript学习第三周总结

周一

1、Math对象:专门提供了数学计算的API

强调:Math不需要创建,直接使用

API:
	1、取整:31、上取整:超过一点点,就取下一个整数
			var num=Math.ceil(num);//小数点位数不能超过15位,否则此方法会失效,只能取整

		2、下取整:无论超过多少,都会省略掉小数部分
			var num=Math.floor(num);

		3、四舍五入取整:
			var num=Math.round(num);//只看第一位小数

		//以上三个方法都是垃圾:都是在取整,而且只能取整
		//以前我们取证的方式:以上三个+*parseInt(str)去掉单位+*num.toFixed(d);
		//*num.toFixed(d):优点:
			1、传入自定义保留小数位数,并且也带有四舍五入的操作
			2、解决浏览器带来的舍入误差:计算机很笨,但是它的记忆力好,而且速度快:笨在何处
                    比如:2-1.6 === 0.399999999999 

				缺点:结果是一个字符串,建议搭配上parseFloat使用

		笔试题:不允许使用toFixed的情况下,自己封装一个函数,由用户传入数字以及保留的小数位数,
            进行四舍五入,返回一个数字
			function toFixed(num,d){
				num*=(10**d);
				num=Math.round(num);
				num/=(10**d);
				return num;
			}
			var result=toFixed(Math.PI,4);
			console.log(result)

	2、乘方和开方
		*乘方:Math.pow(底数,幂); -> 更简化的方法:底数**幂
		开方:Math.sqrt(num); -> 仅仅只能开平方

	3、*最大值和最小值:
		var max/min=Math.max/min(a,b,c,d,e,f,g,....);//自动在你传入的数字中找到最大值或最小值
		
		问题:本身不支持数组参数
		解决:固定用法:Math.max/min.apply(Math,arr);//apply具有打散数组的功能

	4、绝对值:把负数变为整数
		Math.abs(-1);//1

	5、***随机数:Math.random():在0~1之间取一个随机的小数
		搭配上parseInt,只能取到0,不可能取到1,意味着取不到最大值
		公式:parseInt(Math.random()*(max-min+1)+min)
		强调:只要以后网页中某一块带有随机的功能,他的底层一定用到了随机数

2、Date对象:日期对象,提供了操作日期和时间的API:

创建:4种

1、*创建一个当前日期 var now=new Date();

	2、*创建一个自定义时间
		var birth=new Date("yyyy/MM/dd hh:mm:ss");

	3、创建一个自定义时间
		var birth=new Date(yyyy,MM,dd,hh,mm,ss);//修改月份,从0~11月,0代表是1月

	4、*复制一个日期:
		为什么:日期的所有的API都是直接修改原日期的,无法获得修改之前的日期
		所以,在执行API之前先进行复制,然后再操作复制后的日期
		var end=new Date(start);

使用:2类

1、两个日期对象之间,可以相减,得到一个毫秒差(大-小),换算出自己想要的任何一部分 - 日期的本质其实就是
保存了一个毫秒数 - 做倒计时的关键点
创建日期的最后一种方式,绝对没人使用:var date=new Date(毫秒数);//计算机元年:1970118点整

2、API:
		分量:时间的单位
		年月日星期:FullYear Month Date Day
		时分秒毫秒:Hours Minutes Seconds Milliseconds
		每一个分量都有一对儿getXXXX/setXXXX
			其中getXXX负责获取一个分量的值
			其中setXXX复制设置一个分量的值
		特殊:
			1、取值范围:
				FullYear - 当前年份的数字
				Month - 0~11
				Date - 1~31
				Hours - 0~23
				Minutes、Seconds:0~59
				Day - 0~60代表星期天,外国人的眼里星期天才是一个星期的第一天

			2、任何人都有set操作,唯独Day没有set

			3、如果希望对某个分量进行加减操作的话
				date.setXXXX(date.getXXXX()+/-n)

			4、格式化日期为本地字符串:
				date.toLocaleString() - 垃圾:具有兼容性问题,我们一般会选择自己封装
                            一个format函数来进行格式化

				用了此方法会失去一些东西:日期的自动进制、日期的所有的API
				但是你也会得到一些东西:字符串的API,你可以解锁更多的操作(替换、切割、
                            截取...)

3、***定时器:

1、*周期性定时器:每过一段时间会执行一次,先等后做,会反复执行,需要自己写停止才能停止
开启:timer=setInterval(callback,间隔毫秒数);
停止:clearInterval(timer);

2、一次性定时器:等待一段时间,只会做一次就结束了
	开启:timer=setTimeout(callback,间隔毫秒数);
	停止:clearTimeout(timer);

两个定时器,看起不同的操作,居然可以相互的转换,两者的底层是一样的!

同步技术:代码必须一行一行的执行,前面的没做完,后面的就只能等着,目前为止几乎所有的代码,都属于同步技术
异步技术:无论我们这一块代码多么好事,也不会卡住后续代码,目前这个技术只有定时器,最牛逼的异步技术(AJAX)

扩展:如何使用JS创建页面DOM元素:

//1、创建空标签
var elem=document.createElement("标签名");
//2、为这个空标签,设置必要的属性或事件
elem.属性名="属性值";
elem.on事件名=function(){操作}
//3、将我们的元素放上到DOM树
父元素.appendChild(elem);

周二

1、BOM:Browser Object Model:浏览器对象模型

专门用于操作浏览器的,但是他使用的不多,远不如ES和DOM,浏览器很多操作都是自带的, 而且BOM没有标准:各个浏览器都有自己的定义,但是大部分浏览器都是一致规范的,唯独老IE (8-)

2、window对象:扮演着两个角色:

1、代替全局对象global:保存着全局变量和全局函数
2、【指代当前窗口本身】
属性:专门获取大小
     1、获取浏览器的完整的大小:outerWidth/outerHeight
     2、*获取浏览器的文档显示区域的大小:innerWidth/innerHeight - 获取每台电脑的浏览器的文档显示区域
     的大小
     3、获取屏幕的完整的大小,跟window没关系:screen.width/height,我们目前学习的都是浏览器应用(网页),
     并不会去做桌面应用
     方法:
	1、*打开链接的新方式:
		1、当前窗口打开,可以后退
			HTML:<a href="url">内容</a>
			      JS:open("url","_self");

		2、当前窗口打开,禁止后退,使用场景:比如电商网站,结账后禁止后退
			HTML做不到了,只有JS可以,也不是window能做到,而是另外一个人
			history:当前【窗口的历史记录】,他其实可以做的事儿就是前进后退
			location:当前【窗口的正在打开的url】,而他有一个API叫做
				location.replace("新url");//叫做替换,不叫作跳转,不会产生历史记录,自
                            然也就不能前进后退,但是网址都替换,网页必然会发生变化

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

		4、新窗口打开,只能打开一个,使用场景:比如电商网站,只允许用户打开一个结账界面
			HTML:<a href="url" target="自定义一个name">内容</a>
			     JS:open("url","自定义一个name");

			解释:其实窗口的底层都有一个名字,如果打开了一个已经开着的名字的窗口,新打开
                    的就会把旧的给替换掉,但是给大家的感觉有一点像是刷新的感觉

		学习完这一块,我们知道了2个点:
			1、以后的跳转,任何标签都可以
			2、提升了用户的体验感
			3、a标签的其他用途:
				1、跳转
				2、锚点
				3、下载:<a href="xx.exe/rar/zip/7z...">内容</a>
				4、打开图片和txt文件:<a href="xx.图片的后缀/txt">内容</a>
				5、直接书写JS - 不需要绑定点击事件:<a href="javascript:js代码;">
                                   内容</a>

	2、打开新窗口/新连接:var newW=open("url","target","width=?,height=?,left=?,top=?");
			特殊:
				1、如果你没有传入第三个参数,那么窗口回合浏览器融为一体,浏览器有多大,
                                   窗口就有多大
				2、如果你传入第三个参数,那么窗口回合浏览器分离开,独立存在
				3、可以拿个变量接住这个窗口,以后用于做其他操作
	3、关闭窗口:window/newW.close()
	4、改变新窗口的大小:newW.resizeTo(新宽,新高)
	5、改变新窗口的位置:newW.moveTo(新X,新Y)
	6、*window提供的三个框:- 换一个浏览器,样式就不一样了
		警告框:alert("警告文字");
		输入框:var user=prompt("提示文字");
		确认框:var bool=confirm("提示文字");
	7、***定时器也是window的:
	8、***window的专属事件:
		1、window.onload事件 - load:加载:等待其他所有的资源加载完毕后才会执行的代码,放在里面
                   的代码其实是要最后才会执行 - 只要把js放在HTML的后面,就不需要此操作
		2、*window.onresize事件 - 窗口如果大小发生了变化,就会触发,搭配上上面的判断
                   innerWidth可以理解为这是JS版本的css媒体查询
		3、***window.onscroll事件 - 滚动事件,一旦滚动就会触发
				1、获取滚动条当前的位置:window.scrollY
				2、获取元素距离页面顶部有多远:elem.offsetTop/offsetLeft

	9、*****本地/客户端存储技术:保存着在浏览器里面的数据
		cookie:淘汰了,存储大小只有2kb,而且操作极其复杂,尤其要到处切割的,最多只能保存30天
		webStorage:H5(概念统称)带来的一个新特性,存储的大小由8mb,永久保存,而且操作非常简单!
			分类2种:
			1、sessionStorage - 会话级,只要浏览器一旦关闭,数据就会死亡
			2、localStorage - 本地级,只要不你清空他,他就永远存在
			两者的用法是一摸一样的,不用创建,可以直接使用

			操作:
				1、添加:xxxxStorage.属性名="属性值";
				2、读取:xxxxStorage.属性名
				3、删除:xxxxStorage.removeItem("属性名");
				4、清空:xxxxStorage.clear();//删全部

周三

BOM的常用对象:最重要的三个东西:定时器、客户端存储技术、event

1、history对象:保存了当前窗口的历史记录(过去的url)
前进:history.go(1);
后退:history.go(-1);
刷新:history.go(0);

2、***location对象:保存了当前窗口的正在打开的url(现在的url)
***程序员必备常识:一个url由及部分组成?分别每个部分有什么? - 以后再学习服务器端和数据库的时候会有
很大的帮助!
 <http://127.0.0.1:8020/js_core_day06/01-3.html>
 <https://www.baidu.com/s?ie=utf-  8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%95%A6%E5%95%A
 6%E5%95%A6&fenlei=256&rsv_pq=0x9b75e6ae0001fc21&rsv_t=932drOVbAzpIfKkyONfjGfo9MpXIcsjMcAYygRaRsVFOgS
 UnROR%2BwBTVBlVu&rqlang=en&rsv_enter=1&rsv_dl=tb&rsv_sug3=6&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&rsv_b
 type=i&inputT=1128&rsv_sug4=1128>
 
 5部分:
      1、协议:https(加密)/http(未加密)/ftp(传输文件) /ws(直播) - 前两个都属于叫做 请求 - 响应 模
         型,专门用于实现网站开发
      2、主机号|ip地址|域名:域名是需要花钱购买的,主机号|ip地址是免费的,127.0.0.1才真的叫主机号,只能
         自己访问自己
      3、端口号:https默认端口为443,http默认端口为80,只有默认端口可以省略不写!
      4、***文件的相对路径|路由:百度加密了 - 如果以后学习了服务器端,我们可以配置好一些选项,用户就可以
         在自己电脑上,看到我们的东西了
      5、***查询字符串|请求消息:前端传输到后端的东西,前端对后端说的话,就是form表单get提交带来的东西

      属性:获取url的5个部分的内容,但是不需要记忆,你直接输出location对象即可查看
	   协议:location.protocal
	   域名:location.hostname
	   端口号:location.port
	   路由:location.pathname
	   请求消息:location.search

      方法:
	   跳转:location="新url" - 替换当前窗口,可以后退
	   跳转后,禁止后退:location.replace("新url");
	   刷新:location.reload();

DOM:原本DOM是可以操作一切结构化文档的,但是再某个版本升级过后,为了方便各类程序员将DOM分为了3部分:

1、核心DOM:无敌的,既可以操作HTML又可以操作XML,但是语法相对比较复杂
2、HTML DOM:只能操作HTML,不能访问一切自定义的东西,但是语法简单
3、XML DOM:只能操作XML数据格式,被淘汰了,被JSON数据格式代替了

   1、查找元素:
	  1、通过关系找元素:前提:至少要找到一个元素,才可以调用关系网
		父:xx.parentNode;
		子:xx.children; - 集合
		第一个儿子:xx.firstElementChild;
		最后一个儿子:xx.lastElementChild;
		前一个兄弟:xx.previousElementSibling;
		后一个兄弟:xx.nextElementSibling;

	  2、直接找元素:2大类:通过HTML的特点去查找元素
		1、var elems=document.getElementsByXXXXXX();//返回的是一个动态集合HTMLCollection
		
		2、第二大类:2个:通过CSS选择器去查找元素
			1、var elem=document.querySelector("任意css选择器");
				缺陷:只能找到单个元素,如果匹配到多个,也只会返回第一个,没找到,返回
                                null
				一次只能操作一个元素,不舒服

			2、***var elems=document.querySelectorAll("任意css选择器");
				优点:
					1、找到了是一个集合,没找到是一个空集合
					2、复杂查找时,非常简单
					3、返回的是一个静态集合NodeList

		面试题:document.getXXX 和 document.queryXXX的区别?
			1、后者更适合复杂查找
			2、动态集合和静态集合的区别?
				1、动态集合:每一次DOM发生变化,他都会悄悄的再次查找页面元素,让页面
                                   和数据保存一致,但是效率也就低下了 - 不支持forEach
				2、静态集合:每一次DOM发生变化,他都不会悄悄的再次查找页面元素,让页面
                                   和数据保存不一致,但是效率也就高了 - 支持forEach
		
   2、操作样式:
	1、内联样式:
		获取:elem.style.css属性名; - 只能获取内联样式
		设置:elem.style.css属性名="css属性值";

	2、样式表样式 - 此生不见
		//获取你想要操作的样式表
		var sheet=document.styleSheets[i];
		//获取此样式表中所有的样式规则
		var rules=sheet.cssRules;
		//数出你想要操作的那个样式规则
		var rule=rules[i];
		//操作
		console.log(rule.style.background);
		rule.style.background="purple"

   3、操作属性:
	1、*获取属性值:
		核心DOM:elem.getAttribute("属性名");
		HTML DOM:elem.属性名

	2、*设置属性值:
		核心DOM:elem.setAttribute("属性名","属性值");
		HTML DOM:elem.属性名="属性值"

	3、删除属性:设置属性值为空字符串,确实某些属性可以算是删除,但是只是删除了属性值,属性名还在,
           而有的属性哪怕只有一个属性名,也会具有作用(checked、href、readonly...)
		*核心DOM:elem.removeAttribute("属性名");
		HTML DOM:elem.属性名="";

	4、判断有没有:垃圾,只能判断有没有,不能判断是什么,推荐用elem.getAttribute("属性名");去获取到
           属性值,自己再写比较运算进行判断
		核心DOM:elem.hasAttribute("属性名");
		HTML DOM:elem.属性名!="";

    4、操作内容 - 你是学习完整的:innerHTML/innerText/value

    5、如何创建元素以及上树:3步
	1、创建空标签:
		var elem=document.createElement("标签名");

	2、为其设置必要的属性和事件
		elem.属性名="属性值";
		elem.on事件名=function(){操作}

	3、上树:3种
		*父元素.appendChild(elem);//在父元素末尾追加一个子元素elem
		父元素.insertBefore(elem,已有子元素);//在父元素里面追加一个子元素elem,但是会放在已有子元素的前面
		父元素.replaceChild(elem,已有子元素);//在父元素里面追加一个子元素elem,但是elem会替换掉已有子元素

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

总结:你觉得DOM在干什么? 答:增、删、改、查(元素、内容、属性、样式)

扩展:

1、input的两个专属事件:onfocus(获取焦点)和onblur(失去焦点)
2、创建变量:在ES6新增了一个let关键字 - 建议忘掉var
   let 变量名=值;
作用:
    1、解决了声明提前,一定要先创建再使用
    2、带来了块级作用域:一个{}就是一个快,此变量只能在那个{}里面使用!
    3、如果用let去当作下标绑定事件,那么他会记录着你当前元素的下标,不再需要自定义下标了!其实forEach
       的那个形参i就是用let创建的!
3、将类数组对象变为普通数组!ES5提供了此API
   接住=Array.from(类数组);

周四

1、递归:简单来说就是再函数之中再一次调用了函数自己,迟早有一天会停下来!

何时使用:专门用于【遍历层级不明确的
情况】 - DOM树和【数据】
如何使用:2function 函数名(root){
        1、第一层要做什么直接做!
	2、判断有没有下一层,如果有下一层则再次调用此方法,只不过传入的实参是自己的下一层
	}
	函数名(实际的根元素/根数据)

算法:深度优先!优先遍历当前节点的子节点,子节点遍历完毕才会跳到兄弟节点
缺陷:不要过多使用,性能相对较差,同时开启大量的函数调用,浪费内存,我们只在一个情况:【遍历层级不明确的情况】

递归 vs 纯循环:
	递归:优点:简单易用
	          缺点:性能低
	纯循环:优点:几乎不占用内存
		缺点:难得很

2、绑定事件:3种方式

1、在HTML页面上书写事件属性:
<elem on事件名="函数名(实参)"></elem>
缺点:
   1、不符合内容(HTML)与样式(CSS)与行为(JS)的分离
   2、无法动态绑定,一次只能绑定一个元素
   3、不支持绑定多个函数对象

2、*在JS中使用事件处理函数属性:
	elem.on事件名=function(){操作}

	优点:
		1、符合内容(HTML)与样式(CSS)与行为(JS)的分离
		2、可以动态绑定

	缺点:
		1、不支持绑定多个函数对象 - 我个人觉得这其实不是缺点

3、*在js中使用事件API:如果不用考虑老IE,他还是不错的
	主流:elem.addEventListener("事件名",callback);
	老IE:elem.attachEvent("on事件名",callback);
	兼容:
		if(elem.addEventListener){
			elem.addEventListener("事件名",callback);
		}else{
			elem.attachEvent("on事件名",callback);
		}

	优点:
		1、符合内容(HTML)与样式(CSS)与行为(JS)的分离
		2、动态绑定
		3、支持绑定多个函数对象
	缺点:有兼容性问题

扩展:

1select&option只要他们可以简化创建元素&上树!
一句话简化4个操作:
   select.add(new Option("innerHTML","value"))

周五

属于BOM的重点只有3个:定时器 + 客户端存储技术 + event(事件对象):

1、事件周期:从事件发生,到所有事件处理函数执行完毕的全过程:
3个阶段:
    1、捕获阶段:由外向内,记录着要发生的事件有哪些
    2、目标优先触发:目标元素->当前点击的实际发生事件的元素
    3、冒泡触发:由内向外,依次执行我们之前记录着的要发生的事件

2、*****获取事件对象event:
     主流:会自动作为事件处理函数的第一个形参传入e
     老IE:event; - 老IE全局有这个变量
     兼容:event;//第一次见到小三上位,不光老IE可用,主流也可用

     得到了事件对象event可以做什么呢?
	  1、***获取鼠标的坐标/位置
		获取鼠标相对于屏幕的坐标:e.screenX/Y
		获取鼠标相对于浏览器窗口/客户端/文档显示区域的坐标:e.clientX/Y
		获取鼠标相对于网页的坐标:e.pageX/Y

	  2、***阻止事件冒泡 - 笔试面试中
		主流:e.stopPropation();
		老IE:e.cancelBubble=true; 
		兼容:e.cancelBubble=true; //第2次见到小三上位,不光老IE可用,主流也可用

		非常想把事件处理函数简化为箭头函数,但是简化后,this就用不了了,需要一个人来代替this
               (当前元素 - 水性杨花),this其实不是什么好东西,他的指向非常的多
3、*****事件委托/利用事件冒泡 - 开发中常用:提升网页性能,有了它我们的事件函数也可以简化为箭头函数了
		优化:如果多个子元素定义了相同 或 相似的事件操作,那么最好只给【父元素定义一次】
		为什么:每一次绑定一个事件函数,其实都是创建了一个事件对象,创建的对象越多,网页的性能
                就越差。
		淘汰了this,他水性杨花,当前元素
		认识一个【目标元素】target:实际触发事件的元素
		主流:e.target;
		老IE:e.srcElement;
		兼容:e.srcElement;//第3次见到小三上位,不光老IE可用,主流也可用

4、***阻止浏览器的默认行为:比如:a标签默认就可以跳转,提交按钮可以提交表单,右键自带一个弹出框,F12
   自带一个控制台,F5自带刷新,F11自带全屏...
		主流:e.preventDefault();
		老IE:e.returnValue=false;
		兼容:e.returnValue=false;//第4次见到小三上位,不光老IE可用,主流也可用
	
		新事件:
			1、右键事件 - window.oncontextmenu
			2、键盘事件:一般用于游戏开发比较多 + 都要搭配上键盘的键码
				*window.onkeydown - 按下和按住都会触发,任何键盘按键都可以触发
				window.onkeypress - 按下和按住都会触发,但是只有数字、字母、回车、空格
                                可以触发,其他人不行
				window.onkeyup - 松开按键才会触发,任何键盘按键都可以触发

5、***获取键盘的键码 - 因为我们不做游戏开发
		e.keyCode; - 可以获取到你按了哪个键,每个键都有自己对应的键码,但是不需要记忆,要么输出
                看,要么百度搜个表

event可以说是BOM之中最最最重要的一个点!

扩展

如果事件委托:
0、脱字符串衣服(引号):eval(str) - 会悄悄的脱掉字符串的衣服再运算
1、如何判断目标元素是什么标签:xx.nodeName - 得到的标签名是全大写组成的
2、事件处理函数可以写为箭头函数->this就会失效,所以必须使用目标元素target
3this的指向 - 难点
     1、单个元素绑定事件this->这个元素
     2、多个元素绑定事件this->当前元素
     3、箭头函数this->外部对象