js第二周

106 阅读8分钟

数据类型的转化

转布尔:

Boolean(x):任何都可以转布尔,只有6个会为false:0,"",undefined,null,NaN,false

比较运算符:>,<,>=,<=,==,!=,===,!==;

结果:布尔值; 默认转化为数字再比较大小; 如果参与比较的左右两边都是字符串,则按位pk每个字符的16进制unicode; 0-9<A-Z<a-z<汉字; 常识:汉字的第一个字:一:unicode号为4e00,ascii号为19968; 最后一个字:龥:unicode号为9fa5,ascii号为40869;

===和==的区别

===不仅数值相同,数据类型也要相同; !==:不带有隐式转化的不等比较

逻辑运算符

&&

全部满足才满足,一个不满足则不满足

||

全部不满足才不满足,一个满足则满足

颠倒布尔值

短路逻辑

如果前一个条件已经可以得出最终结论,那么没有必要看后续

&&短路:条件&&(操作);

如果一个条件满足才执行后一个操作,如果前一个条件不满足则不管后续操作

||短路:e||window.event

实现浏览器兼容问题,二选一

位运算

左移:m<<n :m*2的n次方;右移:m>>n:2/2的n次方;底数只能为2,虽然可以设置幂,但不能设置底数

赋值运算

i++:递增每次固定加一;i+=1:累加,每次固定加几可以改变

i++和++i的区别

单独使用时,放前放后无所谓,效果一样 但是如果参与了别的表达式,变量中的值都会+1 前++:【返回的是加了过后】的新值; 后++:【返回的是加了过前】的旧值;

三目运算

效果等同于if

语法

条件1?操作1:默认操作; 条件1?操作1:条件2?操作2:默认操作

特殊

1、默认操作不能省略,省略后会报错; 2、如果操作有多句话,还是推荐使用if分支,多句操作再同一行不方便以后维护

计算机带有摄入误差

num.toFixed(d):d代表保留的小数位数,会四舍五入运算;返回的是字符串,需要用parseFloat

获取字符串的第一个字符的ascii码

str.charCodeAt(0)2

自定义函数

声明方式

function 函数名(形参列表){ 函数体; return 返回值; }

直接量方式

var 函数名=function(形参列表){ 函数体; return 返回值; }

return

return的本意:退出函数;return后面跟着一个数据,会将其返回到全局作用域中,只返回不保存,需要用变量接住;调用函数:var result=函数名(实参列表);

作用域

全局作用域

全局变量和全局函数,在任何地方都可以使用

函数/局部作用域

局部变量和局部函数,在函数调用时内部可用

变量的使用规则

优先使用局部的,局部没有找全局,全局没有就报错

特殊

1:不要对着未声明的变量直接赋值:a=1,会导致全局污染; 2:局部的东西全局不能使用; 3:哪怕没有写return,其实最后也有return值,只不过是一个return undefined; 4:return一般只会出现在函数的最后,而且只能出现一个;

声明提前

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

按值传递

两个变量之间进行赋值,如果传递的是原始类型的值:修改一个变量,另一个变量是不会受到影响到,其实是复制了一个【副本】给对象;如果传递的是引用类型的对象:修改一个变量,另一个变量其实也会受到影响,因为大家操作的其实是同一个【地址值】 - 浅拷贝

预定义全局函数

编码

var code=encodeURIComponent("内容");

解码

var 原文=decodeURIComponent(code);

判断无穷大

isFinite(num):true->有效数字,false->无穷大;NaN、Infinity、分母为0都会为false

switch分支

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

特殊

1:case的比较不带隐式转换的;2:只要一个case满足后,会将后面所有的操作全部做,所以需要加上break;3:default可以省略不写,如果条件都不满足的情况,则什么事都不会执行

面试:if和switch比较

switch:好处:执行效率相对较高,缺点:必须要知道最后的结果才能使用,case不能做范围判断; if:好处:可以做范围判断,缺点:执行效率相对较低; 开发时:用哪个都无所谓, 代码优化:尽量的将if换成switch

do while循环

var 循环变量=几; do{ 循环体; 循环变量的变化; }while(循环条件)

do while循环和while的区别

只看第一次: 如果第一次大家都满足,两者其实没区别; 如果第一次大家都不满足。while一次都不会执行,而do...while至少会执行一次

终止循环语句

break:退出整个循环 continue:退出本次循环,还会继续做下一次

关联(hash)数组

下标是可以自定义的数组

创建

1、先创建一个空数组:var arr=[]; 2、添加自定义下标并且赋值:arr["自定义下标"]=新值;

访问

arr["自定义下标"];

遍历关联数组

for in 循环

不能设置从哪里开始到哪里结束,所有的操作都是自动的

语法

for(var i in 数组名){ i;//自动得到每一个洗标 数组名[i];//当前hash数组中的元素了 } 既可以遍历hash数组,也可以遍历索引数组

关联(hash)数组原理(面试)

【hash算法】:将字符串交给hash算法,会得到一个尽量不重复的数字,但是字符串的内容相同,那么得到的数字也一定是相同; 【添加元素】:将自定义下标交给hash算法,得到一个数字(地址值),把要保存的数据放进去了; 【读取元素】:将指定的自定义下标交给hash算法,得到一个和添加时完全相同的数字(地址值),通过这个地址值可以拿到当初保存的东西;

Api数组转字符串

var str=arr.join("自定义连接符");如果没有传入实参,则和toString效果一致,默认都是用,隔开

面试:完成无缝拼接

var arr=["h","e","l","l","o"," ","w","o","r","l","d"]; console.log(arr.join(""));

将数组元素拼接为页面元素(数据渲染)

1:【获取数据】 var arr=["-请选择-","北京","南京","西京","东京","重庆"]; 2:【将数组转为了字符串,并且拼接上了标签】 var str=""+arr.join("")+""; 3:【让字符串上DOM树,innerHTML是识别标签】 sel.innerHTML=str;

实现:二级联动:4个关键点

【1】、必须使用二维数组,细分每一个城市,并且二维数组的顺序要和之前的一维数组对应 【2】、select.onchange=function(){} - 状态改变事件:只有选中项发生变化时,才会触发 【3】、select可以直接获取当前选中项的下标,而不需要自定义下标:select.selectedIndex; 【4】、其实绑定事件,等号左边部分就是你的函数名

Api拼接数组

var newArr=arr.concat(值1,arr2....);

特殊

【1】此方法不会修改原数组,必须拿一个变量去接住结果(返回的一个新数组); 【2】哪怕拼接的是一个数组,悄悄的打散数组,单个添加;

Api截取子数组

var subArr=arr.slice(starti,endi+1);

特殊

【1】此方法不会修改原数组,必须拿一个变量去接住结果(返回的一个新数组) 【2】含头不含尾 【3】如果只传入了一个实参,则为从starti开始,到末尾 【4】如果两个实参都省略,则复制了一份 - 深拷贝!两者互不影响 【5】支持负数参数,-1代表倒数第一个,-n代表倒数第n个

Api删插替

splice:

删除

var dels=arr.splice(starti,n);从starti位置开始删除n个元素;返回的是你删除的元素组成的数组

插入

var dels=arr.splice(starti,0,新值1,....);原来starti位置的元素以及后续元素都会被向后移动;没有删除元素,也有返回值,返回的是一个空数组而已

替换

var dels=arr.splice(starti,n,新值1,....);var dels=arr.splice(starti,0,新值1,....);删除的个数 和 插入的个数不必相同

Api翻转数组

arr.reverse(); 仅仅只能翻转

Api排序

arr.sort():默认转为字符串,按位PK每个字符的unicode(ascii)

升序

arr.sort(function(a,b){return a-b;}):a是后一个数,b是前一个数;如果a>b,就会返回一个正数,说明后一个数>前一个数;如果a<b,就会返回一个负数,说明后一个数<前一个数;如果a==b,就会返回一个0,说明后一个数==前一个数;而sort的底层就能通过你返回的值来判断要不要帮你交换位置

降序

arr.sort(function(){return b-a;})

手写冒泡排序

for(var j=1;j<arr.length;j++){ for(var i=0;i<arr.length-j;i++){ if(arr[i]>arr[i+1]){ var m=arr[i]; arr[i]=arr[i+1]; arr[i+1]=m; } } }

Api栈和队列

添加元素和删除元素的新方式

一端封闭,只能从另一端进出

队列

只能一端进入,另一端出

栈:开头添加

arr.unshift(新值,....)

栈:开头删除

var first=arr.shift():一次只能删除一个,而且一定是删除的第一个元素;开头进出,会导致每个元素的下标都会发生变化

栈:结尾添加

arr.push(新值,...);

栈:结尾删除

var last=arr.pop();一次只能删除一个,而且一定是删除的最后一个元素

队列的使用

队列:以上4个API是可以混搭的; 开头入:arr.unshift(新值,....); 结尾出:var last=arr.pop(); 结尾入:arr.push(新值,...); 开头出:var first=arr.shift();

二维数组

数组的元素,又一次引用了一个数组

语法

var peoples=[ ["吴飞华",18,"洪兴"], ["冯伟朕",19,"东英"], ["封永跃",20,"三联"] ];

访问

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]) } }

String的基础概念

多个字符组成的【只读】字符【数组】!

【只读】

字符串所有的API都不会修改原字符串,只会返回新的字符串

【数组】

跟数组有相同点:【1】字符串可以使用下标获取某个字符【2】字符串可以使用length获取字符的长度【3】字符串可以遍历得到每个字符【4】字符串可以使用数组不修改原数组的API(concat、slice)【5】所有数组直接修改原数组的API,字符串都不可以使用

JS内置对象(引用类型):11个

String Number Boolean -> 包装类型;Array Function Date(日期) Math(数学) RegExp(正则:验证);Error(错误);Object(面向对象);Global(全局对象)

包装类型

专门封装原始类型的值,将原始类型悄悄的变成了引用类型的对象(属性和方法)

为什么

前辈们觉得比如字符串经常会被我们拿来做一些操作,为了方便我们程序员,提供了包装类型,把字符串变成了一个对象,提供了我们一些操作字符串的属性和方法;【本身原始类型的值】,不带有任何属性和方法,意味着不能使用.去做操作的;为什么undefined和null不能使用.,他们俩没有提供过包装类型(没有任何属性和方法)

何时使用

只要你试图使用.去操作原始类型的值的时候,包装类型就会悄悄出现

何时释放

方法一旦调用结束,包装类型就会自动释放