js-----1.1

146 阅读17分钟

第一天

1、*****Array API:

1、*****排序:2种方式:
	1、鄙视时:手写冒泡排序:从第一个元素开始,依次比较相邻的两个元素,如果前一个>后一个,两者就交换位置
		公式:	
		for(var j=1;j<arr.length;j++){
			for(var i=0;i<arr.length-j;i++){
				if(arr[i]>arr[i+1]){
					var middle=arr[i];
					arr[i]=arr[i+1];
					arr[i+1]=middle;
				}
			}
		}
		console.log(arr);

	2、正式开发中:数组提供了排序的API:
		arr.sort();
		问题1:默认将数据们转为字符串,按位PK每个字符的ASCII码,如果希望按照数字排序那怎么办?
		解决:
		arr.sort(function(a,b){//匿名回调函数,不需要我们调用它,它自动调用,创建这个API的前辈帮我们提前准备好的
			//console.log(a);//后一个数字
			//console.log(b);//前一个数字
			return a-b;//如果return,返回 是一个正数,说明后一个比前一个大
						 //如果return,返回 是一个负数,说明前一个比后一个大
						 //如果return,返回 是一个0,说明一样大
						 //而我们sort方法,根据你返回的数字,来判断要不要交换位置
		})

		问题2:只能升序排列,如何降序?
		arr.sort(function(a,b){
			return b-a;
		})

	强调:排序非常重要,切忌,只要以后网页中有任何排序功能,他的底层一定是一个数组,因为只有数组可以排序

2、栈和队列:添加元素和删除元素的新方式:
	 栈:其实就是数组,只不过一端封闭,只能从另一端进出的数组
	 何时:优先使用最新的数据,现实生活中,情况不多:公交车、电梯...
	 如何:
		开头进:arr.unshift(新值,...);//添加元素的新方式:向前添加:缺点:会修改其他元素的下标,不要传入数组参数,会变成一些二维,一些一维
		开头出:var first=arr.shift();//删除元素的新方式:向前删除一个,一次只会删除一个:缺点:会修改其他元素的下标

	       *结尾进:arr.push(新值,...);//添加元素的新方式:向后添加:很棒:完美的代替了:arr[arr.length]=新值 和 arr=arr.concat(新值),不要传入数组参数
		结尾进:var last=arr.pop();//删除元素的新方式:向后删除一个,一次只会删除一个

	 队列:其实就是数组,只不过只能从一端进,另一端出的数组
	 何时:希望按照先来后到的顺序,现实中多得很
		开头进:arr.unshift(新值,...);
		结尾进:var last=arr.pop();

	       *结尾进:arr.push(新值,...);
		开头出:var first=arr.shift();

	 ES3的数组的API就算学完了,后面ES5还有,等待我们学习

2、二维数组:数组的元素,又引用着一个数组

何时:在一个数组内,希望再次细分每个分类
创建:
  var arr=[
	["张三丰",128,5500],
	["张翠山",38,4500,],
	["张无忌",18,3500]
  ];

访问:arr[行下标][列下标];
特殊:列下标越界,返回undefined
      行下标越界,报错,因为undefined不能使用[]

遍历二维数组:必然两层循环,外层循环控制行,内层循环控制列
	for(var r=0;r<arr.length;r++){
		for(var c=0;c<arr[r].length;c++){
			console.log(arr[r][c]);
		}
	}

总结:ES3数组告一段落
  1、数组的基础(创建、访问、添加、length、遍历)
  2、API:10个(转字符串、拼接、截取、删插替、翻转、排序、栈和队列)
  3、二维数组

3、*****String的基础概念:

什么是字符串:多个字符组成的【只读】字符【数组】(只读:明天我们学习的所有的字符串的API都是不修改原字符串的,只会返回一个新字符串)
和数组有相同的地方:
	1、字符串中的个数:str.length;
	2、获取字符串中某个字符:str[i];
	3、遍历字符串
	4、所有数组不修改原数组的API,字符串也可以使用 -(concat(还不如+隐式转换拼接)、slice)

和数组也有很多很多的不同点:
	所有数组直接修改原数组的API,字符串都不可以使用,比如排序只有数组才可以
	字符串也有很多很多属于自己的API,明天我们慢慢学

***引用/对象类型:11个
       *String Number Boolean -> 他们三个拥有包装类型
       *Array *Function Date(日期) Math(数学) *RegExp(正则:验证)
	Error(错误)
       *Object(面向对象开发方式)
	Global(全局对象) - 在浏览器中被window对象(保存着全局变量和全局函数,理论上来说确实应该对象名.操作,只不过全局对象.可以省略不写)给代替了

***包装类型:专门将原始类型的值封装为一个引用类型的对象
     为什么:原始类型的值原本是没有任何属性和方法,意味着原始类型本身就是不支持.操作的
	     但是前辈们发现字符串经常会被我们程序员所操作
	     为了方便我们程序员为这三个人提供了包装类型(提供了很多很多的属性和方法)
   何时使用:只要视图用原始类型的变量调用属性或方法时,自动包装
   何时释放:方法调用完毕后,自动释放包装类型,并且返回数据(又悄悄的变成了原始类型)

   为什么undefinednull不能使用. - 没有提供包装类型

第二天

1、*****String API:

前辈们创建好的,我们可以直接使用,只有字符串也可以使用
1、转义字符:\
	作用:1、将字符串中和程序冲突的字符转为原文
			比如双引号中还想再放入双引号 "\""
	      2、包含特殊功能的符号 - 几乎没用
			\n:字符串换行
			\t:制表符  ->  大空格tab
	      3、*输出unicode编码的字符 - 搭配正则
			\uXXXX:第一个汉字:\u4e00		ascii:19968
				最后一个汉字:\u9fa5		ascii:40869

2、*大小写转换:将字符串中的每个英文字母统一的转为大写 或 小写
	  何时:只要程序不区分大小写,就要【先统一】的转为大写或小写,再比较(验证码)
	  如何:
		大写:var upper=str.toUpperCase();
		小写:var lower=str.toLowerCase();

3、获取字符串中指定位置的字符:var newStr=str.charAt(i) 还不如 str[i]

4、获取字符串中指定位置的字符的ascii码:
	var ascii=str.charCodeAt(i); - 甚至搭配上循环,我们可以得到每一个字的ascii码
   根据ascii码转回原文:
	var 原文=String.fromCharCode(ascii);

5、***检索字符串:检查索引:获取关键字的下标
	var i=str/arr.indexOf("关键字",starti);
	从starti位置开始,查找右侧【第一个关键字】的位置
	starti可以省略,默认从0位置开始查找
	返回值:找到了,返回的是第一个关键字的第一个字符的下标
		*没找到,返回-1,我们不关心下标为多少,只关心为不为-1
	作用:以后只要希望判断有没有 或者 不希望有重复的
	强调:数组也能使用此方法,后期才添加上的 - 比如老IE数组就不支持此方法
	鄙视题:默认只能获取到第一个关键字的下标,如何才能获取所有关键字的下标呢?
		var i=-1;		      
		while((i=str.indexOf("no",i+1))!=-1){
			console.log(i);
		}

6、*截取子字符串:3种
	*var subStr=str/arr.slice(starti,endi+1);//和数组的用法一样
		      .substring(starti,endi+1);//用法几乎和slice相同,但是不支持负数参数
		     *.substr(starti,n);//支持负数参数,n代表的截取的个数,不必考虑含头不含尾,某些情况用此方法可能更简单

7、拼接字符串:var newStr=str.concat("新字符串") === 还不如+运算

8、*替换字符串:本身这个方法非常强大,但是由于我们暂时还不会正则表达式,只能写一个字符串固定关键字,导致我们替换不完整
	var newStr=str.replace("关键字"/RegExp,"新内容");

9、*****切割/分割字符串:
	作用:将字符串转为数组
	var arr=str.split("自定义切割符");
	特殊:1、切割后,切割符就不存在
	      2、切割符是一个空字符串"",切散每一个字符

扩展: 1、创建元素:var elem=document.createElement("标签名");

2、为他设置必要的属性或者事件: elem.属性名="属性值"; elem.onclick=function(){操作}

3、渲染到DOM树上/上树: 父元素.appendChild(elem);

第三天

都是五颗星的内容 一.正则表达式

什么是:定义字符串中字符出现规则的表达式;

何时:切割.替换[验证]

如何使用:语法:/正则表达式/

1.最简单的正则:关键字原文"no"-->/no/后缀

后缀:g:global找全部i:忽略大小写

2.备选字符集:/^[备选字符集]$/

   强调:(1)一个中括号只管一个字符
       (2)正则表达式默认只要满足就不管后续,我们希望从头到尾完全匹配,-->解决:前加^后加$---只要做验证就必须加
       特殊:如果备选字符集中的ascii码是连续的那么可以用-省略掉中间的部分.
           比如:一位数字[0-9]
               一位字母[A-Za-z]
               一位数字,字母,下划线[0-9A-Za-z]
               一位汉字[\u4e00-\u9fa5]
               除了xxx之外的:[^0-9] - 很少使用,范围太广了

3.预定义字符集:前辈们提前定义好的,方便我们程序员简化备选字符集

    一位数字:\d====[0-9]
    一位数字、字母、下划线:\w === [0-9A-Za-z_]
    一位空白字符:\s 包括:空格、换行、制表符
    一位除了换行外的任意字符:.	-	很少使用,范围太广了
    
    **建议:优先使用预定义字符集,如果预定义满足不了,自己在写备选字符集补充**
    问题:不管是预定义字符集还是备选字符集,一个都只管一位

4.量词:规定一个字符集出现的次数:

1.有效明确数量
    (1)字符集:{n,m}前面相邻的字符集至少n个,最多m个
    (2)字符集:{n,}前面相邻支付及至少n个,多了不限
    (3)支付及:{n}前面相邻字符集,必须n个
    
 2.没有明确数量  
    (1)?:前面相邻字符集,可有可无,最多一个
    (2)*:前面相邻字符集,可有可无,多了不限
    (3)+:前面相邻字符集至少一个,多了不限

5.选择和分组:

选择:在多个规则中选一个
		规则1|规则2
分组:将多个子规则临时组成了一组规则
		(规则1|规则2)

6、指定匹配位置:

^:开头
$:结尾
特殊:两者同时使用:前加^后加$:表示从头到尾要求完全匹配 - 只要你做验证就【必须】这么写

7、密码强度验证:

    4位密码,数字和字母的组合,至少出现一位数字和大写字母
	/^[0-9A-Za-z]{4}$/
	预判公式:
		/^(?![0-9]+$)规则$/ -> 不能全由数字组成
		/^(?![a-z]+$)规则$/ -> 不能全由小写字母组成
		/^(?![0-9a-z]+$)[0-9A-Za-z]{4}$/; - 不能全由数字组成,也不能全由小写字母组成,也不能由数字和小写的组合组成 - 至少一个大写字母

		
		//4位密码,数字和字母的组合,至少出现一位数字和大写字母
		var reg=/^(?![0-9a-z]+$)(?![A-Za-z]+$)[0-9A-Za-z]{4}$/
		
		//4位密码,数字和字母的组合,至少出现一位数字和大写字母和小写字母
		var reg=/^(?![0-9a-z]+$)(?![A-Za-z]+$)(?![A-Z0-9]+$)[0-9A-Za-z]{4}$/

下午

2、支持正则的字符串的API:替换、切割 1、切割:var arr=str.split(reg); - 简单

2、*****替换:很有可能出现在鄙视中
	1、基本替换法:缺陷:替换的新东西是固定的
		str=str.replace(/正则表达式/后缀,"新内容")
		//replace支持正则,并且搭配上后缀就可以找到全部关键字进行替换

	2、高级替换法:
		str=str.replace(/正则表达式/后缀,function(a,b,c){
			//第一个形参是正则匹配到的关键字
			//第一个形参是正则匹配到的关键字的下标
			//原文本身
			return a.length==2?"**":"***";
		})

	3、格式化:
		var str="500103198602215933";
		var reg=/(\d{6})(\d{4})(\d{2})(\d{2})(\d{4})/;
		str=str.replace(reg,function(a,b,c,d,e,f,g,h){
			//在replace的时候,正则出现了分组,我们会得到更多的形参
			//有多少个分组就会多出现多少个形参
			//第一个形参是正则匹配到的关键字
			//第二个形参会得到第一个分组获取到的部分
			//第三个形参会得到第二个分组获取到的部分
			//...
			return b+"年"+c+"月"+d+"日"
		})
		console.log(str);

	总结:何时前加^后加$(验证),何时又该加后缀g(替换)?

3、正则对象: 1、创建: 直接量:var reg=/正则表达式/后缀; 构造函数:var reg=new RegExp("正则表达式","后缀");

2、API:验证
	var bool=reg.test(用户输入的内容);
	true->验证通过	false->验证失败

扩展

1、每一个input都应该绑定一个获取焦点事件onfocus - 显示提示文字

2、每一个input都应该绑定一个获取失去事件onblur - 获取用户

输入的内容,然后和正则验证判断给出正确和错误的样式

3、form记得绑定提交事件onsubmit:阻止return false;

第四天

1.Math对象

强调:不需要创建,直接使用
属性:Math.PI====3.1415926 不需要我们创建Math带有此属性

API:
    取整:三种
     1、上取整:超过一点点,就取下一个整数
		Math.ceil(num);
	   2、下取整:无论超过多少,都会省略掉小数部分
		Math.floor(num);
	   3、四舍五入取整:
		Math.round(num);

	   //以上三个都是垃圾:都是在取整,只能取整
    2.**取整的方式:以上三个 + *parseInt + *num.toFixed(d)
    个人最推荐*num.toFixed(d):优点:可以四舍五入保留指定的小数位数
		缺点:结果是一个字符串,建议搭配上parseFloat()
    *鄙视题:不允许使用toFixed的情况下,自己封装一个函数,实现toFixed的功能,要求能有四舍五入,并且保留小数位数的功能
    function round(num,d){
			num*=Math.pow(10,d);
			num=Math.round(num);
			num/=Math.pow(10,d);
			return num;
		}
		var result=round(3.5,0);
		console.log(result);

	2、乘方和开方
	  *乘方:Math.pow(底数,幂) - 代替连乘操作 
	   开方:Math.sqrt(num) - 只能开平方

	3、*最大值和最小值:
		var 最大的/最小的=Math.max/min(a,b,c,d,e,f,g,....);
		问题:本身不支持数组参数
		解决:固定用法:
			var 最大的/最小的=Math.max/min.apply(Math,arr);
			apply其实有两个功能:1、借用   2、悄悄的将数组打散为单个元素

	4、绝对值:把负数转为整数
		Math.abs(负数)

	5、*****随机数:网页上出现了随机的功能,底层一定用到了随机数
		Math.random():在0-1之间取出一个随机的小数
		可能取到0,但是不可能取到1,意味着取不到最大值
		公式:
		parseIny(Math.random()*(max-min+1)+min);

	Math还提供了三角函数,但是我们不会使用到

2、Date对象:日期对象 创建:4种 1、*创建一个当前日期时间: var now=new Date();

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

  3、创建一个自定义时间:
	var birth=new Date(yyyy,MM-1,dd,hh,mm,ss);//修改月份,从0开始的,0-11

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

操作:
  1、两个日期对象之间可以相减,得到一个毫秒差,换算出自己想要的部分 - 日期的底层其实就是毫秒数
	创建的最后一种方式:var date=new Date(毫秒数);//不用,不好猜

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

	 2Day星期,没有set方法

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

  4、格式化日期为字符串:本地格式
	date.toLocaleString();//本地日期格式 - 垃圾:具有兼容性问题,在老IE上显示效果不一样

引用类型:11个 *String *Number *Boolean *Array *Function *Date *Math *RegExp Error *Global Object

第五天

上午

Error对象--错误对象

1.浏览器自带四种错误类型:可以快速找到自己的错误

语法错误:SyntaxError----多半都是符号写错了
引用错误:ReferenceError-----没有创建就直接使用了
类型错误:TypeError----不是你的方法,你却使用了
范围作物:RangeError-----只有一个API会遇到:num.toFixed(d)--d的取值范围只能在(0-100之间);

2.只要发生错误.就会报错,会导致后续代码终止,我们不希望

错误处理:就算发生错误,我们也不希望报错,而是给一个错误提示,让后续代码依然可以执行

语法:

    try{
        只放入可能出错的代码
    }cathc(err){
        发生错误后才会执行
        console.log(err);//:err就是我们的错误提示--英文
        console.log("中文的错误提示")
    }

try...cathc的性能非常差:几乎放在里面的代码效率都会被降到最低

可以用一个技术代替:分支

开发经验:记住一切的客户端输入/用户输入都是坏人--不必担心只要做好防护就没什么问题,(!isNaN.正则);

3.抛出自定义错误

    throw new Error("自定义错误信息")---只要是报错就会卡住后续代码
    

下午

*****function对象

1.创建:3种方式:

(1)声明方式:function 函数名(形参,....){
        函数体;
        return 返回值;
}-------会完整的声明提前
(2)直接量方式:var 函数名=function(形参,...){
        函数体;
        return 返回值;
}-----只有函数名部分会提前,但是赋值留在原地,通过这个方法我们可以看出,其实函数名就是一个变量名;
(3)构造函数方式:
var 函数名=new function("形参1","形参2"..."函数体;return 返回值")
何时使用:如果你的函数体不是固定的是动态拼接的一个字符串
var arr=[1,2,324,545,3,12,3,44,43,];
var user=prompt("请进行排序,如果输入a-b则为升序,如果输入b-a则为降序")
var compare-new function("a","b","return"+user)
arr.sort(compare);

2.调用时,如果还有return记得接住:var result=函数名(实参,...)

3.考点:

(1)创建的方式
(2)变量的使用原则:优先使用局部的,局部没有就找全局,全局没有就报错
(3)声明提前
(4)案值传递
(5)重载overload:相同的函数名,根据传入的实参的不同,可以自动选择对应的函数进行执行
    为什么:减轻程序员的压力
    问题:js的语法不支持重载
        js不允许多个同名函数同时存在,如果同时存在,最后的会覆盖之前所有的
    解决:在[函数中]有一个对象----arguments对象
        什么是arguments:只能在函数中使用,自动创建,是一个类数组对象(支持下标,length,遍历)
        作用:可以接住所有的传入的实参
   *****arguments可以做的事:
           ①可以实现重载:通过函数内部判断arguments的不同.执行不同的操作
           ②以后有没有形参都无所谓
           ③正式开发中,有可能会将多个函数整合为一个函数--减轻程序员的压力
(6)匿名函数:没有名字的函数
    (1)匿名函数自调:
        为什么:节约内存,因为匿名函数,没有变量引用着,用完,垃圾回收期就会发现此引用类型没有人引用着,则垃圾回收器的计数为0,垃圾回收器就会把此函数释放掉
        (function(){
                以后可以代替全局代码写法,尽量的不要再去外部书写代码
        })();
    (2)匿名函数回调:将函数作为一个实参,传递给其他函数用
        1.*学习回调的目的:让你知道哪些东西叫做回调函数,只要是匿名函数,没有自调就是回调.
        arr.sort(function(){})
        str.replace(reg,function(){})
        elem.onclick=function(){}
        2、以后ES6有个技术,箭头函数:简化一切回调函数的
        3、了解了一下回调函数的原理