前端第二阶段第二周的总结

132 阅读6分钟

1、数据类型转换

1、强制转换:

	1、转字符串:String(x);//万能的,完全等效于隐式转换,还不如+""
	2、转数字
             1、*parseInt(str/num) - 专门用于将字符串转为整数的
		   执行原理:从左向右依次读取每个字符,碰到非数字字符则停止,一来就不认识则为NaN
	     2、*parseFloat(str); - 专门用于将字符串转为浮点数的
		   执行原理:几乎和parseInt一致,但是认识第一个小数点
	     3Number(x);//万能的,但是没什么用,千万不要手动使用,完全相当于隐式转换,还不如-0 *1 /1	

	3、转布尔值:Boolean(x);//万能的,完全等效于隐式转换,还不如!!x5个会转为false0,"",null,undefined,NaN
		我们不会自己手动转换为布尔,但是在循环和分支的条件中,不管你写的是什么,最后都会悄悄的变成一个布尔值

2、运算符和表达式:

1、*算术运算:+ - * / %
   隐式转换:默认,转为数字,再运算
       特殊:1、+运算,只要碰上一个字符串,则变为拼接
	    2、- * / %,纯数字组成的字符串也可以转为数字,但是非纯数字字符串则为NaN
			NaN参与任何算术运算结果都为NaN
2、比较运算符:> < >= <= == != === !==
     隐式转换:默认转为数字,在判断大小
         特殊:1、如果两边都是字符串,则是按位PK每个字符串unicode号(ascii码)0-9<A-Z<a-z<汉字
	       2、NaN不能用===比较,要用!isNaN(x);
	       3、undefined===null
3、逻辑运算符:&& || !
	短路逻辑:
	  &&:条件&&(操作);	相当于	简单的if
	  ||:做浏览器兼容性:实现了两个值二选一
4、位运算:
   左移:m<<n:m*2的n次方
   右移:m>>n:m/2的n次方

5、赋值运算:一句话执行两个操作,先运算,在保存回去
	+= -= *= /= %= ++ --
	前++和后++:
	1、单独出现,没区别
	2、如果参与了别的表达式(和别的代码写在一起的):
		变量中的值始终都会+1
		返回:前++,返回的是递增后的新值
		      后++,返回的是递增前的旧值

6、三目运算:简化if...else  if...else if...else
	语法:条件?操作:默认操作;
	      条件1?操作1:条件2?操作2:默认操作
	特殊:1、默认操作不能省略
	      2、操作只能是一句话,不能有多个操作

扩展:

  1、解决舍入误差:var str=num.toFixed(d);//d保留的小数位数
  2、获取字符串中第一个字的ascii码:var ascii=str.charCodeAt(0);

1、自定义函数

1、创建:2种

	1、声明方式:function 函数名(形参,...){
				函数体;
				return 结果;
		     }
	2、直接量方式:var 函数名=function(形参,...){
				函数体;
				return 结果;
		       }

2、调用并且接住结果:var result=函数名(实参,...);

3、作用域:

	1、全局:成员,在任何地方都可以使用
	2、函数:成员,在当前函数调用时内部可用
	带来了变量的使用规则:优先使用自己的,自己没有找全局,全局没有就报错
	问题:1、全局污染,建议操作任何变量之前记得先创建var一下
	      2、全局用不到局部的,但是现在可以return出去了

4、声明提前:

    在程序正式执行之前,会将var声明的变量和function声明的集中提前到当前作用域的顶部,但是赋值留在原地

5、按值传递:两个变量之间进行赋值

如果传递的是原始类型,两者互不影响,因为是复制了一个副本给对方
如果传递的是引用类型,两者相互影响,因为使用的是同一个地址值(浅拷贝)

2、预定义全局函数,拓展:

1、编码解码:encodeURIComponent/decodeURIComponent - 浏览器自带此功能
2parseInt/Float/eval/isNaN

3、分支:新的switch...case...

switch(变量/表达式){
	case1:
	操作1;
	break;
	case2:
	操作2;
	break;
	default:
	默认操作;
}
注意:有的地方需要加break,有的地方不需要
      default可以省略

1、***循环结构:反复执行 相同 或 相似的操作:

1while(循环条件){循环体;变量变化;} - 不确定循环次数的时候
2do{循环体;变量变化;}while(循环条件)
鄙视/面试中:whiledo...while的区别
	只看第一次:如果第一次大家都满足,两者没有区别
		    如果第一次都不满足,while什么都不执行,do...while至少会执行一次
3、***for(循环变量;循环条件;变量的变化){ - 明确次数
	循环体;
   }
4、*循环流程控制语句:退出循环:break;//退出整个循环
			      continue;//退出本次循环,根据需求判断自己还需不需要执行后续的循环
后面可能还会学到for in forEach for of各种循环

2、*****数组的基础:

1、基础概念:

	什么是数组:在一个内存(变量)中保存了多个数据的一个集合结构
	何时:只要存储多个相关的数据,都要用数组集中保存
	为什么:一个好的数据结构,可以极大地提升我们程序员的开发效率

2、创建:2种

	1、*直接量:var arr=[值1,...];
	2、构造函数:var arr=new Array(值1,...); - 还有一个坑:var arr2=new Array(5);//创建了一个长度为5的空数组

3、访问:

   数组名[下标]; -- 当前元素
   添加/修改:数组名[下标]=新值;
   特殊:读取元素,下标越界 -- 返回undefined
	 添加元素,下标越界 -- 下标不连续,导致变成一个稀疏数组

4、数组的三大不限制:

1、不限制长度
2、不限制类型
3、不限制下标越界

5、数组唯一的属性:arr.length; 获取到数组的长度

三个固定套路:
	1、末尾添加:arr[arr.length]=新值;
	2、获取倒数第n个:arr[arr.length-n]
	3、删除倒数n个:arr.length-=n

6、遍历数组:对数组中的每个元素执行 相同 或 相似的操作:

for(var i=0;i<arr.length;i++){
	arr[i];//当前元素
}

7、*如何释放一个引用类型:

   请看清楚这个引用类型的数据有几个变量引用着,每个变量都要释放后,才能真正的释放干净
	建议:我们的代码都要封装到一个函数中,函数中的变量会自动释放

8、索引数组:下标都是数字组成的数组

   关联(hash)数组:下标是可以自定义的
   为什么:索引数组的下标无具体的意义,不便于查找
   如何使用:
	1、创建:2步
		1、先创建一个空数组:var arr=[];
		2、为数组添加自定义下标并且添加元素值:arr["自定义下标"]=新值;
	2、访问:arr["自定义下标"]
	3、强调:hash数组length永久失效,永远为0!
	   遍历hash数组:不能使用for循环,必须使用for in循环 - 专门用于遍历hash数组准备的方式。
		for(var i in arr){
			arr[i];
		}
	   for in虽然不能定义从哪里开始,到哪里结束,专门用于遍历hash数组的
	   个人推荐:索引数组依然使用for循环,hash数组再用for in
	4、***hash数组的原理:
		hash算法:将字符串,计算出一个尽量不重复的数字(地址值)
			  当字符串内容相同,则计算出的数字也一定是相同的
		添加元素:将自定义下标交给hash算法,得到一个数字(地址值),把我的元素保存到了这个地址值之中
		读取元素:将指定的自定义下标交给hash算法,得到一个和添加时完全相同的数字(地址值),根据地址值找到之前保存的东西
	5、*****js里面一切的东西都是对象:除了undefined和null,【一切对象的底层都是hash数组】

3、*****Array的API:其实就是函数,只不过这些函数是前辈们提前定义好的,我们程序员可以直接使用的,这些方法只有数组可用

1、*数组转字符串:

	var str=arr.join("自定义连接符");
	固定套路:
	  1、笔试题:将数组中的内容拼接在一起形成一句话/单词;
		无缝拼接:var str=arr.join("");
	  2、将数组的元素拼接为DOM页面元素
		//数据
		var arr=["-请选择-","北京","南京","西京","东京","重庆"];
		//转为字符串,并且拼接好了标签
		var str="<option>"+arr.join("</option><option>")+"</option>";
		//渲染到DOM树上
		sel.innerHTML=str;

2、*数组拼接:添加新元素的新方式:

	根据你传入的实参全部拼接到arr的末尾
	var newArr=arr.concat(新值1,...);
	特殊:1、不修改原数组,只会返回一个新数组
	      2、concat支持传入数组参数,悄悄的将你的传入的数组打散为单个元素后在拼接

3、*截取子数组:

	根据你传入的开始下标截取到结束下标
	var subArr=arr.slice(starti,endi+1);
	特殊:1、不修改原数组,只会返回一个新数组
	      2、含头不含尾
	      3、endi可以省略不写,会从starti位置一直截取到末尾
	      4、其实两个实参都可以省略不写:从头截到尾:深拷贝:和以前的按值传递的浅拷贝不同,是复制了一个副本给对方,两者互不影响了

以上的API都不会修改原数组

以下的API都会修改原数组

4、*删除、插入、替换:

	删除:var dels=arr.splice(starti,n);//n代表删除的个数
	  特殊:其实splice也有返回值,返回的是你删除的元素组成的一个新数组
	插入:arr.splice(starti,0,值1,....);
	  特殊:1、插入新的元素会将原有元素和后续元素都推到后面去
		2、其实插入也有返回值,只不过没有删除任何元素则为一个空数组
		3、千万不要直接插入一个数组,会变成一个部分二维数组
	替换:arr.splice(starti,n,值1,...);
	  特殊:删除的元素个数不必和插入的元素个数一致

5、翻转数组:

    arr.reverse(); - 以后不会使用