JS学习第二周

77 阅读8分钟

数据类型转换

强制类型转换

转字符串

1、x.toString();//undefined和null不能使用,不能用.调用方法
2、String(x);//万能的,但是没什么用,完全相当于隐式转换,不如+""
都没用.因为页面上的一切数据都是字符串

转数字

1、parseInt(str/num);用于将字符串转为整数的
执行原理:从左向右依次读取每个字符,碰到非数字字符则停止,一来就不认识则为NaN

2、parseFloat(str); 用于将字符串转为浮点数的
执行原理:几乎和parseInt一致,但是认识第一个小数点

3、Number(x);//万能的,但是没什么用,完全相当于隐式转换,不如-0 *1 /1 \

转布尔值

Boolean(x);//万能的,但是没什么用,完全相当于隐式转换,还不如!!x
注意:0,"",undefined,null,NaN,false会转换为false,其余都为true

运算符和表达式

算术运算符 + - * / %

隐式转换:默认,转为数字,再运算
特殊:1.+运算,只要碰上一个字符串,则变为拼接
2.- * / %,纯数字组成的字符串也可以转为数字,但是非纯数字字符串则为NaN
NaN参与任何算术运算结果都为NaN

比较运算:> < >= <= == != === !==

结果:布尔值
隐式转换:默认,左右两边都会悄悄的转换数字,再比较
特殊:1、如果左右【两边】参与比较的都是字符串,则是按位PK每个字符的十六进制的unicode号(十进制ascii码);
2、NaN参与任何比较运算结果都为false,甚至不认识自己,
解决:!isNaN(x); true->有效数字 false->NaN\

3、undefined==null;
问题:==区分不开undefined和null,怎么才能区分开?
全等:===,要求值和数据类型都要相同,换句话说,就是不再带有隐式转换的比较运算 !==,不带有隐式转换的不等比较

逻辑运算符

隐式转式:悄悄的都变为布尔值,然后再综合比较
&&:全部条件都满足,结果为true 只要一个条件不满足,则为false

||:全部条件都不满足,结果为false 只要一个条件满足,则为true

!:颠倒布尔值

自定义Function

什么是函数:需要先定义好,可以反复调用的一个代码段
何时使用:1、不希望打开页面立刻执行 2、以后可以反复的使用 3、希望绑定在页面元素上\

创建函数:

  1、【声明方式】创建函数:
	function 函数名(形参,...){
		函数体;
		return 返回值;
	}

   2、【直接量方式】创建函数:
	var 函数名=function(形参,...){
		函数体;
		return 返回值;
	}

调用

var 接住返回的结果=函数名(实参,...);

作用域

1、全局作用域:全局变量 和 全局函数,特点:在页面的任何位置都可以使用

2、函数/局部作用域:局部变量 和 局部函数,特点:在【当前函数调用时内部可用】

导致变量的使用规则:优先使用自己的,自己没有找全局,全局没有就报错
特殊:缺点: 1、千万不要在函数中对未声明的变量直接赋值 - 导致全局污染,解决:尽量变量使用前都要记得先var一下
2、局部可用全局的,但是全局不能用到局部的 - 解决:看上面,搭配上return

声明提前

在程序正式执行之前将var声明的变量(轻)和function【声明的】函数(重)都会悄悄的集中定义在当前作用域的顶部,但是赋值留在原地(永远不会自己使用,只会干扰我们的判断)

按值传递

两个变量之间进行赋值

如果传递的是【原始类型】的值: 修改一个变量,另一个变量是不会受到影响的,其实是复制了一个副本给对方

如果传递的是【引用类型】的对象: 修改一个变量,另一个变量就会收到影响了,两者使用的是同一个地址值(浅拷贝)

分支结构:根据条件选择部分代码执行:if分支 switch分支

语法:
  switch(变量/表达式){
	case1:
	操作1;
	break;
	case2:
	操作2;
	break;
	default:
	默认操作;
  }

特殊:1、case的比较不带隐式转换的
2、问题:默认只要一个case满足后,会将后面所有的操作全部做完
解决:break;
建议:每一个case的操作后都跟上一个break 有的地方可以不加break:
1、最后的一个操作default可以省略break
2、如果中间多个条件,做的操作是一样的,也不需要
3、default可以省略,如果条件都不满足的话,什么事都不会做到

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

1、while(循环条件){循环体;变量变化;} - 不确定循环次数的时候
2、do{循环体;变量变化;}while(循环条件)
3、for(循环变量;循环条件;变量的变化){ - 明确次数 循环体; }
4、循环流程控制语句:退出循环:break;//退出整个循环continue;//退出本次循环,根据需求判断自己还需不需要执行后续的循环

数组的基础

基础概念:

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

数组的创建

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

访问:

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

数组的三大不限制:

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

数组唯一的属性:

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

遍历数组:

对数组中的每个元素执行 相同 或 相似的操作:
for(var i=0;i<arr.length;i++){
arr[i];//当前元素
}

如何释放一个引用类型:

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

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

关联(hash)数组:下标是可以自定义的
为什么:索引数组的下标无具体的意义,不便于查找
如何使用:
1、创建: 先创建一个空数组:var arr=[];
为数组添加自定义下标并且添加元素值: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数组】

Array的API

1.arr to string

var str=arr.join("自定义连接符");

2.数组拼接

添加新元素的新方式:
根据你传入的实参全部拼接到arr的末尾
var newArr=arr.concat(新值1,...);
特殊:

        1、不修改原数组,只会返回一个新数组
        2concat支持传入数组参数,悄悄的将你的传入的数组打散为单个元素后在拼接
        

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();
注:以后不常使用