数据类型转换
1.强制装换
1.var str = xxx.to.strong xxx.不能是undefinet和null
2.var str=strong()万能的,完全等效于隐式转换,不如+""
2.转数字 专门为字符串转数字准备的两种方法
1.parseInt 不识别小数点
2.parseFloat 识别第一个小数点
注意点:如果一开始就碰到非数字字符串就会变为NaN
3.转布尔类型:
Boolenan();
万能的、不会手动调用,不如!!();
只有这6位是false:0,undefined,null,Nan,false,其他全部为true
注意:在if或者for循环条件中,会转换成一个布尔值
-----------------------------------------------------------------------------
运算符:
算数运算符:+ - * / %
注意点:
1、%= 取余 判断奇偶性
2、有隐式装换,默认转为数字在进行运算
3、+ 运算碰上字符串,则为拼接
- * / % :字符串也可以转为数字,前提是必须是有纯数字组成的字符串,不是数字则为NaN
---------------------------------------------------------------------------------
比较运算符:> < >= <= == != === !==
结果都是:布尔值
作用:比较或者判断
注意: > < >= <= == != 具有隐式转换,默认转为数字,在比较大小
NaN参与比较运算结果都为false,普通的比较运算无法判断某个值是否为NaN
解决方法:判断一个值是否为NaN可以用!isNaN
=== 要求数值相同,数据类型相同,没有有隐式转换
!== 没有隐式转换
---------------------------------------------------------------------------------
逻辑运算符:&& || !
作用:综合比较,结果也为布尔值
&& 全部满足,才满足,有一个不满足,则不满足
|| 全部不满足,其中有一个满足,则满足
! 点到布尔值
注意:&& || !具有隐式转换:左右两边都会转为布尔值,在综合比较结果
&&短路逻辑作用:简化if
语法money>=500&&(money*=0.8);
短路逻辑:如果前一个条件满足,才执行后一个操作,如果前一个条件不满足,则不管后续操作
---------------------------------------------------------------------------------
位运算:
左移:m<<n - m*2的n次方
右移:m>>n - m/2的n次方
---------------------------------------------------------------------------------
赋值运算:+= -= *= /= %= ++ --
i++等效于i+=1等效于i+i=1
++i和i++的区别:单独使用,没有区别 ,参与表达式变量中的值都会加+1
++i返回计算之后的新值 i++返回计算之前的旧值
---------------------------------------------------------------------------------
三目运算
作用:简化 if...else 和 ...else... if..... else......if
语法:
1、条件?操作:默认操作
2、条件?1操作1:条件2?操作2:默认操作
代码:
asc>=48&&asc<=57?"数字":(asc>=65&&asc<=90)||(asc>=97&&asc<=122)?"英文":asc>=19968&&asc<=40869?"汉字":"其他"
四舍五入运算:to.Fixed
---------------------------------------------------------------------------------
自定义函数:需要提前预定好,以后可以反复使用的代码段
创建方式:
1.
1、声明方式创建函数:用一个关键字function做声明
function 函数名(形参列表){
函数体;
return 返回值;
}
2、直接量方式创建函数:函数名其实就是一个变量名
var 函数名=function(形参列表){
函数体;
return 返回值;
}
return本意:退出函数
注意:调用函数时,如果有return,需要用一个变量接收结果,return一般只会出现在函数的最后,而且只能出现一个
如:
function f1(a, b) {
var sum = a + b;
return sum;
}
var result = f1(1, 2);
console.log(result);
---------------------------------------------------------------------------------
作用域:2种
全局作用域:全局变量和全局函数,在任何地方都能使用
局部作用域:局部变量和局部函数,在(函数内部使用)
注意:作用域带来了变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错
1、不要对着未声明的变量直接赋值:num=1;会导致全局污染
解决方案:创建变量时:写入var
---------------------------------------------------------------------------------
声明提前:
3、***声明提前:鄙视重点 - 祖师爷留下的问题之一,真正开发绝对不会用到,只会出现在鄙视之中
原理:
在程序正式执行之前,
会悄悄地将var声明的变量和function声明的函数,
集中提前到当前作用域的顶部,
变量比函数轻,
但是赋值留在原地
明说:自己写代码绝对不会碰到,只要我们遵守原则:1、先创建后使用 2、变量名和函数名尽量的不要重复
只有鄙视中碰到,如果你以后碰到先使用在创建,或者经常重复变量名,很有可能就是在考你声明提前
先转为我们提前后的样子,再去判断
-------------------------------------------------------------------------------------------
4、***按值传递:两个变量之间进行赋值
如果传递的是原始类型的值:两者互不影响,因为其实是复制了一个副本给对方
修改一个变量,另一个变量是不会受到影响到,其实是复制了一个【副本】给对象
如果传递的是引用类型的对象:其实目前你已经学过了两个了,Array和Function,JS中不是原始类型就是引用类型:如果传递的是引用类型的对象:其实变量a根本就没有保存住对象,只是保存了对象的地址值
两者就会相互影响,因为两者用的是同一个地址值
修改一个变量,另一个变量其实也会受到影响,因为大家操作的其实是同一个【地址值】 - 浅拷贝
---------------------------------------------------------------------------------------------
预定义全局函数(在任何一个地方都可以使用):前辈门提前写好,我们可以直接使用,
1、
问题:url中不允许出现多字节字符,如果出现会乱码
utf-8编码格式下,一个汉字,占3字节
解决:发送前,前端将多字节字符编码为单字节字符(数字、字母)
发送后,后端接住,然后将单字节字符解码为原文
如何:
编码:var code=encodeURIComponent("剑风传奇");
解码:var 原文=decodeURIComponent(code);
其实这个东西在某次浏览器更新后,当前就淘汰了!浏览器现在自带此功能
2、isFinite(num):判断num是不是无穷大,true->有效数字,false->无穷大
哪些会为false:NaN、Infinity、分母为0,所以有多个都为false,不能用来判断是不是NaN
3、牛逼的:parseInt/Float、isNaN、eval
---------------------------------------------------------------------------------------------
分支结构语句:switch...case.....; 根据条件的不同,选择一部分代码执行
语法:
switch(变量/表达式){
case 值1:
操作1;
break;
case 值2:
操作2;
break;
default:
默认操作;
}
特殊:1、case的比较不带隐式转换的
2、问题:默认只要一个case满足后,会将后面所有的操作全部做完
解决:break;
建议:每一个case的操作后都跟上一个break;
有的地方也可以省略break:
1、最后的一个操作default可以省略break
2、如果中间多个条件,做的操作是一样的,也可以省略掉中间的操作
3、default可以省略不写,如果条件都不满足的情况,则什么事都不会执行
注意:
switch:好处:执行效率相对较高
缺点:必须要知道最后的结果才能使用,case不能做范围判断
2、if 好处:可以做范围判断
缺点:执行效率相对较低
--------------------------------------------------------------------------------------------
循环结构:
1、var 循环变量=几;
while(循环条件){
循环体;
循环变量的变化;
}
2、var 循环变量=几;
do{
循环体;
循环变量的变化;
}while(循环条件)
3、for(var 循环变量=几;循环条件;循环变量的变化){
循环体;
}
建议:优先使用for循环,不确定循环次数的时候再用while补充
4、终止循环语句:break;//退出整个循环
continue;//退出本次循环,还会继续做下一次
-----------------------------------------------------------------------------------
数组的基本:一个变量名可以保存多个数据
创建方式:
1.直接量方式
var arr = [值1,值2,值3,值4,值5];
2.构造函数方式:
var arr = nwe.Array(值1,值2,值3,值4,值5);
缺陷:面试/鄙视中:new Array(3);这是什么意思 - 创建了一个长度为3的空数组
访问:数组名[下标] = 某个元素;
特殊:读取元素,下标越界,返回的事undefinet
添加元素,下标越界 - 在新位置添加元素,结果:不好的,下标不在连续会变成稀疏数组,再去遍历,一定会得到很多很多的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 = [];
2.添加自定义下标并复制:arr[’自定义下标‘] = 新值;
比如:
var gl=[];
gl["name"]="盖伦";
gl["攻击力"]=100;
gl["防御力"]=10;
gl["生命值"]=1000;
3.访问自定义下标
arr["自定义下标"];
遍历自定义下标:
语法:for (var i in 数组名) {
}
特点:for .....in 既可以遍历索引数组,也可以遍历关联(hash)数组
建议:索引数组依旧使用for遍历
关联(hash)数组使用for....in....
-----------------------------------------------------------------------------------------------
数组的API
1.数组转为字符串
1.var str = arr.join(自定义连接符)
特殊:arr.join如果没有传入实参效果和toString效果一样,默认都是用,隔开
arr.join可以将数组的元素拼接为页面元素(数据渲染)
注意点:arr.join不会修改原数组,必须拿一个变量接收结果
如:
获取数据:
var arr=["-请选择-","北京","南京","西京","东京"];
将数组转为了字符串,并且拼接上了标签
var str="<option>"+arr.join("</option><option>")+"</option>"
让字符串上DOM树,innerHTML是识别标签
sel.innerHTML=str;
实现:二级联动:4个关键点
1、必须使用二维数组,细分每一个城市,并且二维数组的顺序要和之前的一维数组对应
2、select.οnchange=function(){} - 状态改变事件:只有选中项发生变化时,才会触发
3、select可以直接获取当前选中项的下标,而不需要自定义下标:select.selectedIndex;
4、其实绑定事件,等号左边部分就是你的函数名
二级联动案例:
//每一个城市
var arr1 = ["-请选择-", "北京", "南京", "西京", "东京", "重庆"];
//二维数组:最大目的就是为了再次细分分类 - 每个城市的区县
var arr2 = [
["-请选择-"],
["-请选择-", "北京区1", "北京区2", "北京区3", "北京区4"],
["-请选择-", "南京区1", "南京区2", "南京区3", "南京区4"],
["-请选择-", "西京区1", "西京区2", "西京区3", "西京区4"],
["-请选择-", "东京区1", "东京区2", "东京区3", "东京区4"],
["-请选择-", "重庆区1", "重庆区2", "重庆区3", "重庆区4"],
]
sel1.innerHTML = "<option>" + arr1.join("</option><option>") + "</option>";
sel1.onchange = function () {
var i = this.selectedIndex;//此属性只有select可以使用,其他标签没得
sel2.innerHTML = "<option>" + arr2[i].join("</option><option>") + "</option>";
}
sel1.onchange();
2.拼接数组:添加元素到末尾的新方式
var new = arr.concat(值1,arr2....)
如:
var arr = [1, 2, 3];
var arrs = arr.concat(4, 5, 6);
console.log(arrs);
注意点:arr.concat不会修改原数组,必须拿一个变量接收结果,(返回一个新数组)
也可以拼接数组
如:
var arr1=[1,2,3];
var arr2=[4,5,6,7];
var newArr=arr1.concat(arr2);
3.截取子数组:
var subArr=arr.slice(starti,endi+1);
注意点:
1、此方法不会修改原数组,必须拿一个变量去接住结果(返回的一个新数组)
2、含头不含尾
3、如果只传入了一个实参,则为从starti开始,到末尾
4、如果两个实参都省略,则复制了一份 - 深拷贝!两者互不影响
5、支持负数参数,-1代表倒数第一个,-n代表倒数第n个
案例:
var arr=[1,2,3,4,5];
var subArr=arr.slice(1,4);
4.删除 插入 替换:
语法:arr.splice;
删除:var dels=arr.splice(starti,n);//从starti位置开始删除n个元素
特殊:返回的是你删除的元素组成的数组 - 有可能你删除的正好是你需要的
注意点:会修改原数组
案例:
var arr = [10, 20, 30, 40, 50,];
var dels = arr.splice(1, 2);
console.log(arr);
console.log(dels);
插入:var dels=arr.splice(starti,0,新值1,....);
特殊:1、原来starti位置的元素以及后续元素都会被向后移动
2、没有删除元素,也有返回值,返回的是一个空数组而已
注意点:会修改原数组
案例:
var arr = [10, 20, 30, 40, 50,];
var dels = arr.splice(1, 0, 25, 35, 45);
console.log(arr);
console.log(dels);
替换:var dels=arr.splice(starti,n,新值1,....);var dels=arr.splice(starti,0,新值1,....);
特殊:删除的个数 和 插入的个数不必相同
案例:
var arr = [10, 20, 30, 40, 50,];
var dels = arr.splice(1, 3, 25, 35, 45);
console.log(arr);
console.log(dels);
注意点:会修改原数组
5、翻转数组:arr.reverse();
仅仅只能翻转
案例:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var arrs = arr.reverse();
console.log(arrs);
6.数组排序
语法:arr.stor;
案例:升序-加匿名函数方式
var arr = [35, 95, 6, 999, 100, 30,]; arr.sort(function(a,b){
return a-b;
})
案例 - 降序-加匿名函数方式
var arr = [35, 95, 6, 999, 100, 30,];
arr.sort(function(a,b){
return b-a;
})
a是后一个数,b是前一个数
如果a>b,就会返回一个正数,说明后一个数>前一个
如果a<b,就会返回一个负数,说明后一个数<前一个数
如果a==b,就会返回一个0,说明后一个数==前一个数
而sort的底层就能通过你返回的值来判断要不要帮你交换位置
栈和队列
作用:添加元素和删除元素的新方式
栈:一端封闭,只能从另一端进出 - 现实生活中较少,何时使用:希望使用到最新的数据的时候
队列:只能一端进入,另一端出 - 现实生活中较多,何时使用:按照先来后到的顺序
栈:
开头入:arr.unshift(新值,....) 添加最前面
开头出:var first=arr.shift();//一次只能删除一个,而且一定是删除的第一个元素,有可能删除的东西就是你需要的东西
案例:
var arr = [2, 3, 4, 5, 6, 7];
arr.unshift(1, 10, 20, 30);
var firet = arr.shift()
console.log(arr);
console.log(firet);
结尾入:*arr.push(新值,...);添加到最后面
结尾出:var last=arr.pop();//一次只能删除一个,而且一定是删除的最后一个元素,有可能删除的东西就是你需要的东西
案例:
var arr = [2, 3, 4, 5, 6, 7];
arr.push(1, 10, 20, 30);
var firet = arr.pop()
console.log(arr);
console.log(firet);
队列:arr.unshift arr.shift arr.push arr.pop混搭就是队列
开头入:arr.unshift(新值,....)
结尾出:var last=arr.pop();
结尾入:*arr.push(新值,...);
开头出:var first=arr.shift();
案例:
var arr = [2, 3, 4, 5, 6, 7];
arr.push(1, 10, 20, 30);
var firet = arr.shift()
console.log(arr);
console.log(firet);
*二维数组:数组的元素,又一次引用了一个数组
何时使用:你希望再一个数组内再次细分分类
如何使用:
var peoples=[
["洗衣机",2000,"海尔"],
["空调",1000,"京东"],
["蓝牙耳机",500,"淘宝"]
];
访问:arr[r][c] - r代表行下标,c代表列下标
特殊:1、列下标越界,返回undefined
2、行下标越界,返回报错,因为行下标越界已经得到undefined再加[]则报错
如何遍历:
固定公式:外层循环遍历行,内层循环遍历列
for(var r=0;r<peoples.length;r++){
for(var c=0;c<peoples[r].length;c++){
console.log(peoples[r][c])
}
}
案例:
var arr = [
['苹果', 13, '不', '淘吧'],
['例子', 12, '买', '京东'],
['香蕉', 11, '不', '网购']
];
for (var i = 0; i < arr.length; i++) {
for (var r = 0; r < arr[i].length; r++) {
console.log(arr[i][r]);
}
}
点击事件
onclick
状态选中改变事件
onchange
开启定时器
setInteravl
关闭定时器
clearInterval
鼠标移入事件
onmouseover
鼠标移出事件
onmouseout