js第二周

68 阅读14分钟

第一天

1.按值传递:

var a=x var b=a 修改a,b不变,修改b,a不变;传递类型如果是一个原始类型,其实是复制了一个副本给对方,两者互不影响 ——传递如果是引用类型,js中不是引用类型(函数,数组,对象都是引用类型)就是原始类型——因为引用类型很大,比原始类型大很多,不能将变量保存在本地,只是保存了一个地址,其实是赋值了自己的地址给对方,两者用的都是同一个地址,任意一个改变,另一个也会变化。——如何释放一个引用类型:每个变量都释放。————今后的代码都要封装为一个函数,函数中的一切变量都会自动释放

2.哈希数组:hash(关联数组)——可自定义下标

好处————索引数组下标无具体意义,不便于查找

如何使用

——1.创建空数组 var arr=[]

——2.自定义下标并赋值 arr["自定义下标"]=新值

——3.访问元素 arr["自定义下标"]

——注意:哈希数组的length失效,永远为0

——遍历哈希数组 for in for(var i in 数组名){ 数组名[i] }for in 不止能遍历哈希数组,也可以遍历索引数组

3.hash原理

——哈希算法:将字符串计算出一个不重复的数字(地址值),字符串内容相同,计算出来的数字也一定是相同的

——添加元素:将指定的自定义下标交给哈希算法得到一个数字(地址值),直接将要保存的数据放到此地址保存起来

——获取元素:将指定下标交给哈希算法,通过地址找到保存到的元素

4.数组API

——1.arr转str: var str=arr.join("连接符 ")——两个固定套路——1.将数组内容拼接成一句话var arr["h","e","l","l"] var str=arr.join("") console.log(str)

——2.将数组拼接成dom元素-渲染页面 ——拿数据var arr["请选择","重庆","天津","北京","上海"]——将数组拼接为页面标签字符串var str="<option>"+arr.join("</option><option>")+"</option>"——传入页面:标签.innerHTML=str

——3.数组拼接:var newArr=arr.concat(新值1,arr1,arr2)——特殊:不改变原数组,只会返回一个新数组,支持传入数组,会将数组打散为单个,元素再拼接进去

——4.截取子数组:var subArr=arr.slice(start,ebdi+1)开始下标和结束洗标——特殊:1.不修改原数组,只会返回一个新数组——2.含头不含尾——3.endi可以省略不写,如果省略,会从starti位置一直截取到末尾——4.strati 也可以省略不写,如果两个实参都省略,那么会从头到尾都完全复制一份,此操作也叫作深拷贝,复制一个副本给对方- 不会影响原数组

——5.删插替:删除——var del =arr.spice(starti,n) n代表删除个数 特殊:虽然他直接修改原数组,但是也有返回值,返回的是被删除的数组数据组成的一个新数组,没有则会返回一个空数组 插入——arr.splice(start,0,新值) 特殊:1.原start位置的元素及后续的都会向后移动 2.尽量不插入数组,不方便遍历 替换——var dels=arr.splice(start,n,新值。。。) 特殊:删除的个数和插入的个数不必相同

6.反转数组——arr.reverse()

7.数组排序

1.——冒泡排序

var arr=[31,21,54,4376,69,8,8,65,643,52,3,321,5,47,69,87,643,524];

		for(var j=1;j<arr.length;j++){
			for(var i=0;i<arr.length-j;i++){
				if(arr[i]>arr[i+1]){
					var m=arr[i];
					arr[i]=arr[i+1];
					arr[i+1]=m
				}
			}
		}
		console.log(arr);

2.——arr.sort

默认:将数组中的元素转为字符串后,再按位PK每个字符的unicode号(ASCII码)

		问题1:希望按照数字升序排列:
			arr.sort(function(a,b){//此函数叫做匿名回调函数,回调函数不需要我们程序员调用,由前辈们创建好,我们学习如何使用即可,其实前辈们的sort方法悄悄的帮助我们调用了

				return a-b;//如果a-b返回的是一个正数:说明后一个>前一个
					   //如果a-b返回的是一个负数,说明后一个<前一个
					   //如果a-b返回的是一个0,说明后一个==前一个
					   //而sort方法会根据你返回的正数、负数、0,来自动考虑要不要交换位置
			})

		问题2:希望按照数字降序排列:
			arr.sort(function(a,b){
				return b-a;
			})

		强调:切记:1、以后只要网页上有功能带有排序,他的底层一定是数组,因为js中只有数组可以排序
			     2、以后只要网页上有随机的功能,那么他的底层一定用到了随机数公式!

8.二级联动

关键点3个

1.——select专属事件 onchange——只有在选中项发生变化后才会触发

2.select专属事件 selectedindex_——获取当前选项中的下标

3.必须使用二位数组再次细分每个数组

第二天

1.栈和队列:

栈:——添加和删除数组元素

——开头进:arr.unshift(值)向前添加,导致其余元素下标都会发生改变

——开头出:var first=arr.shift()向前删除,一次只能删除一个,会返回一个新数组(被删)其余下标会改变

——结尾进:arr.push(值) -向后添加

——结尾出:var last=arr.pop()-向后删除,会返回一个数组(被删除的)

队列:

——其实就是数组,一端进,一端出

——开头进结尾出:——arr.unshift(新值)+var last=arr.pop()

——结尾进开头出:arr.push(新值)+var first=arr.shift()

2.二维数组:

创建:var arr=[[1,2,3],[3,4,5],[6,7,8]]

访问:arr[[行下标][列下标]]

特殊:列下标越界——返回undefined,—列下标越界——报错

3.数组API:

——1.判断:

every:每一个,要求所有元素满足条件,才会为true,只要有一个不满足为false,非常类似于我们的&&

var bool=arr.every(function(val,i,arr){
                                //val - 当前的值
                                //i - 当前的值的下标
                                //arr - 当前数组本身
                                return 判断条件;
                        })

some:有一些,要求只要有一个元素都满足条件会为true,所有元素都不满足则为false,非常类似于我们的||

                        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.filter(function(val,i,arr){
			return 判断条件;
	          	})

汇总:

		var result=arr.reduce(function(prev,val,i,arr){
			return prev+val;
	          	},基础值)
                            
                            相当于 prev=sum
                            prev+=val

4.es6箭头函数
固定公式:function去掉,()和{}加=>如果形参只有一个,那么()可以省略,如果函数体是一句话,那么{}也可以省略,如果函数体只有一句话,并且是return,那么return和{}都可以省略。

5.字符串——string
——1.和数组相同点:

字符串中的个数: str.length  
获取某个字符 str[i]  
遍历字符串  
数组中不修改原数组的API——字符串.(concat-slice

——2.引用类型:

string Number Boolean——包装类型  
Array Function Date Math RegExp——正则  
Error(错误)
*Object(面向对象开发方式)  
Global(全局对象)—— 只有在浏览器中被window对象代替了, 自然保存着全局变量和全局函数,只不过window可以省略不写,有一天我们会去学习node.js这个后端语言,而在node.js中全局对象就叫做global  

包装类型:专门用于将原始类型的值封装为一个引用类型的对象的 为什么:原始类型的值原本就是没有任何属性和方法,意味着原始类型本身是不支持.去做任何操作的

但是前辈们发现字符串经常会被我们程序员所操作,为了方便我们程序员将这三个人提供了包装类型(提供了属性和方法)

何时使——只要你试图使用原始类型的变量调用属性或方法的时候,自动包装

何时释放——方法调用完毕后,自动释放包装类型,又变成了原始类型

为什么null和undefined不能使用. - 因为前辈们没有给他们俩提供包装类型

第三天

1、StringAPI:——就是一些只有字符串可以使用的函数,不需要我们创建,直接使用

——1、转义字符:
作用:

		1、将字符串中和程序冲突的字符转为原文
			"\""         '\''
		2、包含特殊功能的符号:
			换行:\n
			制表符:\t	->	大空格,就跟你敲tab按键效果一样
		3、*输出unicode编码的字符:
			\u4e00    -   ascii码:19968
			\u9fa5     -   ascii码:40869

——2.大小写转换:

作用:验证码
转大写:Var upper=str.toUpper Case()
转小写 var lower=str.toLower Case()

——3.获取字符串中指定位置的字符:

str.charAt(i)===str[i] 

——4.获取字符串中指定位置的字符的ASCII:

   var ascii =str.charCodeAt(i)
   通过ASCII码转回原文
   var 原文=string。fromCharCode(ascii)
   

——5、***检索字符串:检查索引,检查下标:获取关键字的下标

	var i=str/arr.indexOf("关键字",starti);
	从starti位置开始,查找右侧第一个关键字的第一个字符的位置
	starti可以省略,默认从0位置开始查找
	*返回值:找到了,返回第一个关键字的第一个字符的下标位置
		没找到,返回-1,其实我们根本不关心下标为多少,我们只关心下标为不为-1
                    
	作用:判断有没有!
	强调:数组也能使用此方法,数组这个方法是后期才添加 上的,原本此方法只有字符串可用,比如老IE的数组就没此方法。
	鄙视题:默认只能获取到第一个关键字的下标,如何才能获取到所有的关键字的下标?
		var str="no zuo no die no can no bibi no";
		var index=-1;
		while((index=str.indexOf("no",index+1))!=-1){
			console.log("找到了,下标为:"+index);
		}

——6.拼接字符串:

var newstr=str.concat("新字符串",....)还不如+运算

——7.截取字符串:

var substr=str/arr.slice(starti,endi+1)——如数组
str.substring(starti,endi+1) 不支持负参数
str.substr(start,n)

——8.替换字符串: var newstr=str.replace("固定关键字"/正则表达式,"新内容")
——9.切割/分割/分割字符串

 作用:将字符串转为数组
 var.arr=str.split("自定义切割符")
 注:1.切割后,切割符就不存在了
 2.如果切割字符串的是"",表示切散每一个字符
 

——10.去掉空白符:

 str.trim/trimStart/trimEnd()

——扩展:js如何创建元素

1.创建空标签:
    var elem=document.createElement(“标签名”)
2.为其设置必要的属性:
    elem.属性名="属性值"
    elem.on事件名=function(){操作}
3.挂载上树/渲染页面:
    父元素.appendChild(elem)

第四天

1.Math对象——不需要创建,直接使用

API:

            1、取整:3种
		1、上取整:超过一点点,就取下一个整数
			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、可以四舍五入,并且保留指定小数位数,d其实就是保留的小数位数
				          2、解决浏览器带来的舍入误差,2-1.6=0.3999999999999这种情况就可以使用toFixed来解决
				缺点:结果是一个字符串,建议搭配上parseFloat()使用

		//*鄙视题:不允许使用toFixed的情况下,自己封装一个函数,由用户传入数字和保留位数,实现四舍五入操作:
			function toFixed(num,d){
				num*=(10**d);
				num=Math.round(num);
				num/=(10**d);
				return num;
			}
			var result=toFixed(Math.PI,2);
			console.log(result);

2.乘方开放

乘方:Math.pow(底数,幂)——底数**幂
开放:Math.sqrt(num)——只能开平方

3.最大最小值

var max/min=Math.max/min(a,b,c,d)
自动比较传入数字的大小
本身不支持数组
解决:固定用法——Math.max/min.apply(Math,arr)
apply 具有打散数组的功能

4.绝对值:——Math.abs(-1)

5.Date对象——日期对象,提供了操作时的API

创建:4种

1.创建一个当前日期
var birth=new Date()
2.创建一个自定义时间
var birth=new Date("yyyy/mm/dd hh:mm:ss" )
var birth=new Date("yyyy,mm,dd,hh,mm,ss" ) 修改月份0-11
3.复制一个日期
因为日期所有的API都是直接修改他原来的,无法修改之前的日期,所以在执行API之前先进行赋值,然后操作复制后的日期
var end =new Date(start)

使用:两类

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

	2、API:
		分量:时间的单位
		年月日星期:FullYear Month Date Day
		时分秒毫秒:Hours Minutes Seconds Milliseconds
		每一个分量都有一对儿getXXX/setXXX的方法
			其中getXXX负责获取一个分量的值
			其中setXXX负责设置一个分量的值
		特殊:
			1、取值范围:
				FullYear - 当前年份的数字
				Month - 0~11
				Date - 1~31
				Day - 0~60代表是星期天,外国人的眼里星期天才是一周的第一天的
				Hours - 0~23
				Minutes、Seconds:0~59
				日期你知道了取值范围,如果你还故意设置超出范围,他很聪明,会自动进制
			2Day,没有set方法

			3、如果希望对某个分量进行加减操作:
				date.setXXX(date.getXXX()+/-n)

			4、格式化日期为本地字符串:
				date.toLocaleString(); - 垃圾:具有兼容性问题,我们一般会选择自己创建一个格式化方法来格式日期
				用了此方法会失去一些东西:日期的自动进制、日期的API
				但是你也会获得一些东西:字符串的API
                             5.getTime() 获取当前时间的毫秒数

3、定时器:

1、周期性定时器:每过一段时间就会执行一次,先等后做
	开启:timer=setInterval(callback,间隔毫秒数);
	停止:clearInterval(timer);

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

同步技术:代码必须一行一行的执行,前面没做完,后面就等着定时器是我们第一次见到的异步技术:无论我这一块代码多么的耗时,也不会卡住后续代码

第五天

1、BOM:Browser Object Model

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

2、window对象:扮演着两个角色: 1、全局对象:保存着全局变量和全局函数 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");
                    5.打开一个空白窗口:
                    var newW=open("about:blank","paoge","width=300,height=300,left=0,top=0");
		     其实窗口的底层都是有一个名字的,如果打开了一个已经开着的名字的窗口的,他会把他关闭掉,再次打开

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

	2、打开新窗口/新链接:newW=open("url","target","width=?,height=?,left=?,top=?");
			特殊:1、如果没有加第三个参数,那么窗口会和浏览器融为一体
			          2、如果你加了第三个参数,那么窗口会脱离浏览器独立存在
	3、关闭窗口:window/newW.close();
	4、改变新窗口的大小:newW.resizeTo(新宽,新高);
	5、改变新窗口的位置:newW.moveTo(新X,新Y);
	6、*window提供了三个框:
		警告框:alert("警告文字");
		输入框:var user=prompt("提示文字");
		确认框:var bool=confirm("提示文字");
	7、*****定时器也是window的
	8、事件:
		1、window.onload事件 - load - 加载:等待其他所有的资源加载完毕后才会执行的代码,放在里面的代码其实要最后才会执行
		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、添加:xxxStorage.属性名="属性值";
			2、读取:xxxStorage.属性名;
			3、删除:xxxStorage.removeItem("属性名");
			4、清空:xxxStorage.clear();