一、数据类型的转换
1、转字符串(xx.toString,String(xx))
2、转布尔
Boolean(xx);(不如!x)
只有6个为false:0,null,undefined,NaN,false,“”,其余都为true
在某些地方会自动带有此方法(如分支条件,循环条件)
二、运算符和表达式
**比较关系运算符**
===(全等)!==(不带隐式转换的不等比较),返回的结果为布尔值。===不具有隐式转换
注意:
1、如果参与比较的两个都是数字,安位PK每个字符的十六进制unicode号(十进制:ASCII码)
0-9<A-Z<a-z<汉字
汉字第一个字:Unicode号为4e00(ASCII为19968)
汉字最后一个字:unicode号为9fa5(ascii为40869)
2、null==undefined结果为true,无法区分。用全等===可以区分开,结果为false
===:数值相同并且数据类型也要相同,也就是不带有隐式转换
例如:String()的执行原理:任何东西都可转为字符串
function String(x){if(x===null){console.log(“null”);}
else if(x===undefined){console.log(“undefined”);}
else{console.log(x.toString);}}
三、逻辑运算
短路逻辑:只要前一个条件已经可以得出最终结论,则后续条件不会再执行
&&:如果前一个条件满足,则后一个操作才执行,如果前一个条件不满足,则后一个操作不执行
实现了一个【简单】的分支,可简化if{},操作只能【用一句话】
语法:条件&&(操作);
例:if(total》=500){total*=0.8}
简化为:total》=500&&(total(0.8))
||:两个值中二选一(用于浏览器兼容)
四、位运算
左移:m<<n 读作m左移ln位,m*(2的n次方)
右移:m>>n 读作m右移了n位,m/(2的n次方)
缺点:底数只能是2
五、赋值运算
+=,-=,*=,/=,++,--(一句话完成了两个操作,先运算再赋值回去)
比如:i+1→ i+=1→ i=i+1
递增i++ 每次只能加1
累加:i+=n 每次加n
++i和i++的区别:
1、单独使用时。放前放后无所谓,都一样
2、如果参与了别的表达式,变量中的值都会+1
3、前++,返回的是加了之后的新值;后++返回的是加了之前的旧值
六、三目运算
用于简化if...else..else if...else
使用语法:
1、条件?操作1:默认操作;
2、条件?操作1:条件2?操作2:默认操作
注意:
1、只能完成【简单】的分支
2、默认操作不能省略,省略则会报错
七、自定义函数(提前定义好的,可以反复使用的代码段)
使用:
**1、创建/定义/声明函数**
a、声明方式
用关键字function进行声明,并不是都有声明方式,只有个别有,而且声明方式一定是最简单的。只有变量、常量、函数具有声明方式。
function 函数名(){函数体;
return 返回值;}
b、直接量方式
var 函数名=function(){函数体
return 返回值;}}
**2、调用函数**
var return=函数名(实参,..)
**解释**:return本意为退出函数,但是如果后面跟着一个数据,则可以将数据返回到全局作用于中,但是仅负责返回,不负责保存,所以需要自己创建一个变量接住函数调用的结果。
return只能写一次,而且最好卸载函数体的后面。
何时使用:并不是任何时候都需要加return,在全局想要使用局部的,或者调用完函数还希望拿到函数的结果在后续还要操作时使用。
八、作用域
1、全局作用域:全局变量和全局函数,在任何位置都可以访问/使用
2、函数/局部作用域:局部变量和局部函数,只能在当前的函数调用时【内部可用】
有了作用域才有变量的使用规则:优先使用自己的,自己没有找全局,全局没有则报错
注意:
不要对未声明的变量直接赋值,会导致全局污染
所有的变量在使用之前都一定要先var,不能对着没有var的变量直接赋值
3、局部变量:(1)直接作用在函数作用域中创建的变量(2)形参
4、声明提前
在程序执行之前,悄悄将var声明的变量和function【声明】的函数集中提前到当前作用域的顶部,但是赋值留在原地。变量比函数更轻(提前到函数前面)
九、按值传递
1、如果传递的是原始类型的值,两个变量之间赋值,做操作,互不影响的
2、如果传递的是引用类型的对象:Array、Function
两个变量之间赋值,做擦欧洲哦,是会相互影响的————因为两个用的是一个地址
十、预定义的全局函数
创建之提前定义好的,可以直接在任何位置使用的函数
1、编码和解码
在网址中不允许出现多节字符,如果出现会导致乱码。Utf-8编码格式下,一个汉字占3个字节
解码: var 原文=decodeURIComponent(code);
编码: var code=encodeURIComponent(“str”);
2、isFinite(num):判断num是不是在有效范围之内
三种情况为false:分母为0,NaN,Infinity
十一、Switch...case分支结构
语法:
Switch(变量/表达式){case值1:操作1;break;case值2:操作2;break;default:默认操作}
注意:
1、默认只要满足一条路,会把后面所有的操作全都做完,所以在操作后面放break。
①但是最后的default不需要加break
②如多连续多个操作时一样的效果,也可以省略中间部分
2、不带有隐式转换
3、default可以省略不写
if与Switch的比较
switch优点:效率相对较高,因为不需要做任何范围判断
缺点:不能实现范围判断,必须要知道用户可能会输入的结果是什么才能使用。
if优点:实现范围判断
缺点:效率相对较低
在js优化中,尽量的将if优化为:三目、短路、switch
十二、do..while循环结构
语法: var 循环变量=几;
do{循环体;循环变量的变化}while(循环条件)
do while和while的区别
只看第一次,如果第一次大家都满足条件,两者没有区别,无非do while更麻烦。
如果第一次都不满足,while一次都不会执行,do while至少会执行一次
循环终止语句:
break:退出整个循环
continue:退出本息循环
十三、数组
var arr=newArray(值1,...)
若var arr=newArray(3);则意为一个长度为3的空数组
如何释放一个引用类型:要看清楚这个引用类型对象有几个变量
**1、索引数组:**
下标都是数字组成的数组————默认数组
*2、关联(hash)数组:**
下标是可以自定义的数组
自定义下标的用处:便于查找
创建关联(hash)驻足:
1、创建一个空数组:var arr=[];
2、添加自定义下标并且赋值:arr[“自定义”]=值
访问hash数组:arr[“自定义下标”];
hash数组的length失效,永远为0,而且下标也不再是一个数字
hash数组的遍历:for in循环
语法:for(var i in 数组名){数组名[i]}
for in循环也可以遍历索引数组,但建议索引数组依然使用for循环
注意:在js中除了undefined和null不是一个对象,万物皆对象,而且一切的底层都是hash数组
**hash数组原理**:
hash算法:将祖父穿交给hash算法,会的到一个尽量不重复的数字,但是字符串内容相同的,那么得到的数字一定也是相同的
添加元素:将自定义的下标交给hash算法,得到一个数组(地址值),把要保存的数据放到那个地址之中
获取元素:将制定的下标交给hash算法,得到一个和添加是完全相同的数字(地址是),得到这个地址之中保存的数据了。
3、数组的API(前辈预定义好的,只有数组可以使用的方法)
(1)数组转为字符串
ar str=arr.join(“自定义连接符”)
特殊:
①如果没有传入实参,则和toString/String完全一样,默认用“,”隔开
②固定套路:a:无缝拼接数组例的内容变成一个字符串
例:var arr=[“h”,“e”,“l”,“l”,“o”]
var str=arr.join(“”)
console.log(str);//输出为“hello”
b:将数组找那个的数组拼接为页面上的元素
例:var arr=[“中国”,“北京”,“重庆”]
var str=“<option>”+arr.join("</option>+<option>")+"</option>"
str.innerHTML=str;//innerHTML可以识别标签
4、拼接数组:添加元素到末尾
var newArr=arr.concat(值1,arr1...)
特殊:
1、此方法不修改原数组,只会返回一个新数组
2、此方法传参支持数组参数,并且会悄悄的打散这个数组,单独传入
5、截取子数组
var subArr=arr.slice(starti,endi+1);
从starti位置截取到恩地+1的位置的元素,组成一个新数组
特殊:
1、此方法不修改元素数组,只会返回一个新数组
2、含头不含尾
3、第二实参可以省略(从starti截到末尾)
第一实参也可以省略:则从头截到尾
(此方法为深拷贝,相当于复制了一个副本给对方。而按值传递为浅拷贝)
4、支持负数参数————(-1)代表倒数第一个
6、删除、插入、替换
删除:var dels=arr.splice(starti,n);//从starti开始删除n个
此方法也有返回值,所有删除的元素组成的一个新数组
插入:arr.splice(starti,0,值1,.);//从starti开始删除0个,插入了新的元素
原来starti位置的元素以及后续元素都会被向后移动
替换: var dels=arr.splice(starti,n,值....);
插入的个数和删除的个数可以随意
7、翻转数组 arr.reverse();
8、排序
1、arr.sort();
特殊:1、默认按照字符串按位PK每个字符的unicode号排序
2、按照数字排序
arr.sort(function(a,b){return a-b;})(升序排列)
arr.sort(function(a,b){return b-a;})(降序排列)
return a-b:如果a>b,返回是一个正数
如果a<b,返回是一个负数
如果a=b,返回是一个0,sort根据返回的结果,来判断原者要不要交换位置
此方法使用到了一个回调函数。回调函数:不需要我们调用的函数,悄悄的带有循环,提供了两个形参,a是后一个数,b是前一个数
注意:js中只有数组可以排序,以后我们遇到网页上任何具有排序功能的案例,底层一定是一个数组
2、冒泡排序
冒泡排序:把数组中每一个数字取出来,前一个和后一个进行比较,如果前一个>后一个,两者就要交换位置
例:var arr=[8,5,3,4,9,1,2];
for(var j=0;j<arr.length-1;j++){
for(var i=0;i<arr.length-j;i++){
if(arr[i]>arr[i+1]{
var m=a[i];arr[i]=arr[i+1];arr[i+1]=m;}}}
9、栈和队列(添加元素的新方式)
栈:一端封闭,只能从另一端进出的操作
开头进:arr.unshift(值1,....);
开头出:var shift=arr.shift();//一次只能删除一个,并且返回删除的元素
缺点:每一次进出都会修改其他人的下标
结尾进:arr.push(值1,....)
结尾出:var last=arr.pop();//一次只能能删掉一个,并且返回删除的元素
优点:不会影响到其他元素的下标
队列:只能从一端进,另一端出
开头进:arr.unshift(值1,...);
结尾出:var last=arr.pop();
结尾进:arr.push(值1,....);
开头出:var shift=arr.shift();
十四、二维数组(数组中的值再次引用了一个数组)
何时使用:在一个数组中再次细分内容
1、创建
var arr=[
[“a”,"b","c"],
["d","e","f"]
]
2、访问 arr[r][c]
列下表越界,但会undefined
行下标越界,报错(因为undefined不能使用[])
3、遍历二维数组
必然需要两个循环嵌套:外层循环控制行,内层循环控制列
for(var r=0;r=arr。length;r++){
for(var c=0,c<arr.[length
循环体}
}
十五、String
string概念:字符串————多个字符串组成的只读字符数组
为什么字符串也可以叫数组呢?
理由:和数组有共同点:
①支持下标————获取某个字符
②支持length————字符的长度
③遍历
④数组不修改原数组的API,字符串可以使用(concat、slice)
不同点
数组修改原数组的API,字符串都不可以使用,但是字符数按也有很多属于自己的API
只读:字符串中所有的API都不会修改原字符串,只会返回新字符串
**String的API**
**1、转字符串**
作用:①字符串中如果出现了和字符串冲突的符号,可用\将其转义为原文
\" \'
特殊功能:
换行:\n 制表符:\t(转换为空格)
可以书写unicode号,表示一个字
\nxxx
如:\n4e00;表示汉字的第一个字
**2、转换大小写**
同意的转为答谢或小写,再比较(例如应用在验证码中,忽略大小写)
大写:var newstr=str.UpperCase();
小写:var newstr=str。toLowerCase();
**3、获取字符串中指定位置的字符的ascii码**
var ascii=str.charCodeAt(i);(下标为i的字符的ascii码)
例如:截取第一个字的ASCII码:var ascii=str.CharCodeAt(0);
通过ascii码转回原文
var 原文=String.fromCharCode(ascii码);
**4、检索字符串**
检查索引/下标:从starti位置开始找右侧的第一个关键字的下标
作用:判断有没有这个字
语法:var i=str/arr.indexOf(“关键字”,starti);
特殊:
①starti可以省略,如果省略则从0开始
②返回值:找到了,返回第一个字符的下标,没找到,返回-1.-1表示没有找到,不是-1则表示找到了。
③数组中也可以使用此方法
④找到关键字的位置
例如:var str=“no zuo no die no can no bibi”;
var i=-1;
while((i=str.indexOf(“no”,i+1))!=-1){
console.log(“找到了:”+i(这个字的下标))}
5、拼接字符串
var newstr=str.concat(str1,str2,..)还不如+运算
6、截取字符串(3种)
①var substr=str.slice(starti,endi+1);
②var substr=str.substring(starti,endi+1)
③var substr=str.substr(starti,n);//n为截取的个数,不必考虑含头不含尾
7、替换字符串
var newstr=str.replace(“关键字”/正则表达式,“新内容”);
8、切割/分割字符串
var arr=str.split(“自定义切割符”)
例:var str=“重庆@北京@西藏@浙江@江苏”
var arr=str.(“@”);
arr=[“重庆”,“北京”,“西藏”,“浙江”,“江苏”]
特殊:
1、切割付可以自定义,切割后返回一个数组,数组中不再包含切割付
2、如果传入的切割符是一个“”,每个字符都会被切开
十六、引用类型对象(11个)
String(字符串) Number(数字) Boolean(布尔) 此三个具有包装类型
Array(数组) Function(函数) Math(数学) Date(日期)
RegExp(正则) Error(错误) Object(面向对象)
Global(全局对象):在浏览器被window对象给代替了,window对象可以省略不写
包装类型:将原始类型的值变为一个引用类型的对象
何时使用:只要在试图用原始类型的值去调用属性或者方法时,会自动套上包装类型
何时释放:属性或方法调用完毕后,包装类型自动释放
undefined和null不能使用的原因:他们不具有包装类型,没有任何的属性和方法
***拓展
1、解决计算带有的摄入误差
var str=num.toFised(保留小数的位数)
按小数位四舍五入,但是返回的是一个字符串
2、JS动画:跟JS没有关系,但是由JS来触发。JS设置css是瞬间的操作,只需要在css中加一个过渡就阔以具有动画了。
3、二级联动(4个重点)
①必须使用二维数组,而且二维数组的数据顺序一定要和一级的对应上
②select专属事件:select.onchange:状态改变事件,选中项发生改变才会触发
③select具有一个属性:this.selectedIndex;获取选中项的下标,只有select不需要自定义下标
④其实绑定事件的部分就是函数名,也可以拿来调用
4、定时器
开启定时器:timer=setInterval(function(){操作;},间隔毫秒数)
关闭定时器:clearInterval(timer);
5、鼠标移入事件
onmouseover
例如(鼠标移入关闭定时器):id名.onmouseover=function(){clearInterval(timer);}
6、鼠标移出事件
onmouseout
7、创建元素并且渲染页面
1、创建空标签
var arr=document.createElement(“标签名”);
2、设置必要的属性或事件
arr.属性名=“属性值”;
arr.on事件名=function(){函数体}————事件都可以在创建时提前绑定上
3、创建号的元素渲染到DOM树上
父元素.appendChild(elem);
例如:创建一个表格在页面上
var arr="李白@刺客@80%#孙膑@辅助@45%#凯@战士@60%"
var ps=arr.split("#")
var table=document.createElement("table")
// 表头
var str=["姓名","职业","剩余生命"]
var tr=document.createElement("tr")
for(var i=0
var td=document.createElement("td")
td.innerHTML=str[i]
tr.appendChild(td)
}
table.appendChild(tr)
// 表体
for(var i=0
var p=ps[i].split("@")
var tr=document.createElement("tr")(创建表格的行)
for(var j=0
var td=document.createElement("td")
td.innerHTML=p[j]
tr.appendChild(td)
}
table.appendChild(tr)(将创建的每一行添加到表格的后面)
}
ym.appendChild(table)