学习JavaScript的第二周

124 阅读13分钟

数据类型转换

强制转换

1、转字符串

1)var str = x.toString

             x不能是undefinednull

2)var string = String(x)

2、转数字

1)、parseInt/Float(str)

2)、Number(x) 相当于隐式转换

3、转布尔

Boolean(x);任何数据都可以转为布尔

只有6个会转为false: 0/""/undefined/null/NaN/false

隐式转换

出现在运算符之中

运算符和表达式

1、算术运算符

符号: + - * / %

2、比较运算符:

符号:> < >= <= == != === !== 结果:布尔值 隐式转换,都转为一个数字,再比较

特殊

1)如果参与比较的左右两边都是字符串,则是按位PK每个字符的十六进制的unicode号(十进制ascii码) 0-9<A-Z<a-z<汉字:常识:汉字的第一个字:一: unicode号: 4e00 - ascii: 19968 ; 最后一个字:龥(yu) Unicode号,为9fa5 ascii为:40869;
2)NaN参与任何比较运算结果都为false,所以没有办法使用普通的比较运算来判断x是不是NaN !isNaN(x);
3)undefined==null
-------------- 区分:undefined===null
-------------- 全等:===要求数值相同,并且数据类型也要相同,不再带有隐式转换;
-------------- ===和!==不在具有隐式转换的不等式

3、逻辑运算符

符号: && || ! 作用:综合比较,结果也是布尔值 &&:全部满足才满足 ||:一个满足则满足 !:颠倒布尔值

短路逻辑

如果前一个条件,已经可以得出最终结论,没有必要看后续
1)、&&短路:如果前一个条件满足,才执行后一个条件;如果前一个条件不满足,则不管后续条件;
目的:简化简单的分支
----------1、一个条件一件事,满足就做,满足就不做 ==if(){}
----------2、简单的操作只能由有一句化

2)、||短路:实现浏览器兼容问题:二选一
--------e=e || window.event

4、位运算

1)、左移:m<<n,读作m左移了n位,翻译:m*2的n次方
2)、右移:m>>n,读作m右移了n位,翻译:m/2的n次方
----------底数只能固定为2,虽然可以设置幂,但是不能设置底数

5、赋值运算

符号:+= -= *= /= %= ++ -- 一句话完成两个操作,先计算,再赋值回去

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

6、三目运算

简化:if..else if...else if...else 语法:看条件满足否,满足则作操作1,不满足则作默认操作
-----------1、条件?操作1:默认操作;
-----------2、条件1?操作1:条件2?操作2:默认操作

特殊:

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

保留小数

num.toFixed(d);//d代表保留的小数位数,会四舍五入运算
缺陷:返回的是要给字符串,建议搭配上一个parseFloat食用最好

自定义函数

创建函数并调用(2种)

1、声明方式创建函数

用一个关键字function做声明 function 函数名(形参列表){函数体;}

2、直接量方式创建函数

函数名其实是一个变量名
var 函数名 = function (形参列表){函数体}
调用函数:函数名(形参列表)

3、return 退出函数

  1. 只不过如果return后面跟着一个数据,会顺便将其返回到全局作用域中,但是只负责返回负责保存;
  2. 在调用函数时,如果有return,要用一个变量接住;
  3. 何时使用:如果若需要拿到函数的结果,以后还要做别的操作,就需要搭配上return。

作用域

1、全局作用域:全局变量和全局函数,再任何地方都可以使用 2、函数/局部作用域:局部变量和局部函数,在函数调用时内部使用

特殊

  1. 千万不要给未声明的变量直接赋值,会造成全局污染,所以在创建变量时一定要写var;
  2. 局部的全局不能用;
  3. 没有写return,其实最后也有return值,只不过是一个return undefined,不喜欢undefined,默认return undefined;
  4. return一般只会出现在函数的最后,而且只能出现一个
  5. 往往前辈们提供的方法,底层都有一个return操作,前辈们觉得以后用这些方法的人,可能还需要拿着这个结果去做别的操作

声明提前

  1. 原理:在程序正式执行之前,会将var声明的变量和function声明的函数,集中提前到当前作用域的顶部,变量比函数轻,但是赋值留在原地
  2. 遵守原则:1、先创建后使用 2、变量名和函数名尽量的不要重复只有笔试中碰到,如果以后碰到先使用在创建,或者经常重复变量名,很有可能就是在考你声明提前,先转为我们提前后的样子,再去判断

按值传递

  1. 若传递的是原始类型的值,修改一个变量,另一个变量是不会受到影响到,其实是复制了一个【副本】给对象;
  2. 若传递的是引用类型的值(例如Array和Function),修改一个变量,另一个变量其实也会受到影响,因为大家操作的其实是同一个【地址值】–浅拷贝

预定义全局函数

  1. 编码和解码(浏览器自带该功能,以后基本不用)
    问题:url中不允许出啊先多字节的字符,如果出现会乱码,在utf-8中,一个汉字占3个字节
    解决:
    -----发送前,前端将多字节字符编码为单字节字符(数字、字母)
    -----发送后,后端接住,然后将单字节字符解码为原文
    语法:
    -----编码:var code = encodeURI("文字");
    -----解码: var 文字 = decodeURI("code");
    -----升级版
    ---------编码:var code = encodeURIComponent(文字);
    ---------解码:var 文字 = decodeURIComponent(code);
  2. isFinite(number) 判断number是否无穷大,true表明是有效数字,false表明是无穷大 为false的情况: NaN、Infinity、分母为0;
  3. 一般用是parseInt/Float,isNaN,eval;

分支结构

switch...case 根据条件不同,选择一部分代码执行 语法:

           switch(变量/表达式){
           case1: 操作1breakcase2: 操作2breakcase3: 操作3breakdefault:操作; 
           break

特殊

  1. case的比较不带有隐式转换

  2. 问题:默认只要一个case满足,会将后面的操作都做完 ---解决:break; ---建议:每一个case的操作后面都跟上一个break,其中有的地方break也可以省略

    1、最后的一个操作default可以省略break
    2、如果中间多个条件,做的操作是一样的,也可以省略掉中间的操作
    
  3. default也可以省略不写,如果条件不满足的情况,则什么是都不会执行

if和switch的比较

switch执行效率相对较高,但必须要知道最后结果才能使用,且不能做范围判断;if可以做范围判断,但执行效率相对较低;在开发时,都可以使用,但在代码优化时,尽量将if换成switch。

循环结构

  1. while循环

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

                whiledo...while的区别        
    除了写法上有区别,只看第一次;如果第一次都满足,两者没有区别;
    如果第—次大家都不满足。while—次都不会执行,而do..while至少会执行一次
    
  3. for循环

  4. 终止循环语句
    -------break 退出整个循环
    -------continue 退出本次循环,还会继续做下一次循环

数组基础

一个变量可以存放多个数据

  1. 总的创建
  • 直接量方式 var arr = [值1,值2,....]
  • 构造函数方式 var arr = new Array(值1,值2...)
    • 缺陷:new Array(3) 创建了一个长度为3的空数组
  • 特殊:
    • 读取元素,下标越界===返回undefined
    • 添加元素,下标越界===在新位置添加元素,结果:不好的===稀疏数组,遍历时会得到很多undefined
  1. 索引数组 下标都是数字组成的数组--默认

  2. hash数组 下标可以自定义的数组

  • 如何创建
    • 创建一个空数组 var arr = [];
    • 添加自定义下标并赋值 : arr["自定义下标"]="新值"
    • 访问:arr["自定义下标"];
    • 遍历:把数组中的每一个元索取出来执行相同或相似的操作
    • 问题:不能使用for循环去遍历关联数组,因为length失效了,关联数组的length永远为0,而且我们下标也不再是一个数字
    • 解决:for in 循环
      • 语法:for( var i in 数组名) {数组名[i]; // 当前hash数组中的元素了}
      • 可以遍历hash数组,也可以遍历索引数组
  • JS中,除了undefined和null不是一个对象,万物皆对象,而【—切对象的底层都是hash数组】
  • hash数组的原理:【面试题】
    • hash算法:将字符串交给hash算法,会得到一个尽量不重复的数字,但是字符串的内容相同,那么得到的数字也一定是相同;
    • 添加元素:将自定义下标交给哈希算法,得到一个数字(地址值),把要保存的数据放进入了;
    • 读取元素:将指定的自定义下标交给hash算法,得到一个和添加时完全相同的数字(地址值),通过这个地址值可以拿到当初保存的东西。

数组的API

  1. 数组转为字符串
    ---- 语法:arr.join("自定义符号");
    ----特殊
    ----------没有传入实参,则和toString效果一致,默认都是用,隔开
    ----------笔试中:完成无缝拼接
    ----------将数组元素拼接为页面元素(数据渲染)

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

----------实现二级联动:3个关键点
---1、必须使用二维数组,细分每一个城市,并且二维数组的顺序要和之前的一维数组相对应
---2、select.onchange =function(){}--状态改变事件:只有选中项发生变化时,才会触发;
---3、select可以直接获取当前选中项的下标,而不需要自定义下标: select.selectedlndex;
---4、其实绑定事件,等号左边部分就是你的函数名;
2) 拼接数组:添加元素到末尾的新方式
var newArr = arr.concat(值1,值2....);
特殊:
----1、此方法不修改原数组,必须拿一个变量去接住结果(返回的是一个新数组)
----2、哪怕拼接的是一个数组,悄悄的打散数组,单个添加;
3) 截取子数组
var newArr=arr.slice(start,end+1);
特殊:
----1、此方法不修改原数组,必须拿一个变量去接住结果(返回的是一个新数组)
----2、含头不含尾
----3、如果只传入了一个实参,则为从start开始,到末尾
----4、如果两个实参都省略,则复制了一份–深拷贝!两者互不影响
----5、支持负数参数,-1代表倒数第一个,-n代表倒数第n个
-----------------------以上的API都不会修改原数组的-----------------------
4) 删插替 splice

  • 删除:arr.splice(starti,n);//从starti位置开始删除n个元素
    • 特殊:返回的是删除的元素组成的数组
  • 插入:var dels = arr.splice(starti,0,新值1,....)
    • 特殊
      • 1、原来starti位置的元紊以及后续元紊都会被向后移动
      • 2、没有删除元素,也有返回值,返回的是一个空数组而已
  • 替换:var dels=arr.splice(starti,n,新值1..…); var dels=arr.splice(starti,0,新值1..…);
    • 特殊:删除的个数和插入的个数不必相同
  1. 翻转数组:arr.reverse(); ---仅仅只能翻转

  2. 排序 手写冒泡排序,从第一个元素开始,依次比较两个相邻的元素,如果前一个>后一个,两者就要交换位置

      var arr = [3, 255, 78, 111, 43, 65, 89]; 
           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; m = arr[i]; 
                     arr[i] = arr[i + 1]; 
                     arr[i + 1] = m;
                  }
             } 
         } 
       console.log(arr);
    

语法:arr.sort();
问题:
------1、默认转为字符串,按位PK每一个字符的Unicode(ASCII)
------2、希望按照数字排序-升序

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

------3、希望按照数字排序-降序
---arr.sort(function(a,b){return b-a;}
切记:以后网页中见到任何带有排序功能的特效,说明它的底层一定是数组,因为JS中只有数组可以排序,先排序再数据渲染

队列和栈

栈:一端封闭,只能从一端进出

何时使用:希望使用到最新的数据的时候
开头入: arr.unshift(新值.....)
开头出:var first=arr.shift(); //一次只能删除一个,而且一定是删除的第一个元素,有可能删除的东西就是需要的东西,会影响其他元素
结尾入: arr.push(新值.....)
结尾出:var last=arr.pop();//一次只能删除一个,而且一定是删除的最后一个元素,不会影响其他元素

队列

只能一端进入,另一端出–现实生活中较多
何时使用:按照先来后到的顺序
开头入: arr.unshift(新值..)
结尾出: var last=arr.pop0;
结尾入: arr.push(新值..);
开头出: var first=arr.shift();

二维数组

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

  1. 何时使用:希望在一个数组内再次细分分类

  2. 如何使用:

        var peoples=[["梨花",18,"女"],
     	["张三",19,"男"],
     	["小红",20,"女"]
     ];
    
  3. 访问: arr[r][c] =====r代表行,c代表列

  4. 特殊:
    ------1、列下标越界,返回undefined
    ------2、行下标越界,会报错,因为行下标越界已经得到undefined再加上[]就会报错

  5. 遍历:

             固定公式:外层循环遍历行,内层循环遍历列
     	for(var r=0;r<peoples.length;r++){
     		for(var c=0;c<peoples[r].length;c++){
     			console.log(peoples[r][c])
     		}
     	}
    

总结:ES3提供的数组

  1. 数组的基础(创建、访问、添加、遍历、hash数组)
  2. 数组的API(10个: join、concat、slice、splice、reverse、sort、push、pop、shift、unshift)
  3. 二维数组

String的基础概念

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

  1. 只读: 字符所有的API都不会修改原文字字符串,只会返回新的字符串
  2. 跟数组有相同点: ------1、字符串可以使用下标获取某个字符 ------2、字符串可以使用length获取字符的长度 ------3、字符串可以遍历得到每个字符 ------4、字符串可以使用数组不修改原数组的API(concat \slice) ----差异:所有数组直接修改原数组的API,字符串都不可以使用!

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

  1. String Number Boolean
    ----包装类型
    --------------专门封装原始类型的值,降原类型悄悄的变成了引用类型的对象(属性和方法);前辈们觉得比如字将串经常会被我们拿来做一些操作,为了方便我们程序员,提供了包装类型,把字符串变成了一个对象,提供了我们一些操作字符串的同性和方法。
    ------何时使用:只要试图使用.操作原始类型的值时,包装类型就会悄悄出现
    ------何时释放:方法—旦调用结束,包装类型就会自动释放
    ------为什么undefined和null不能使用.,他们没有提供过包装类型(没有任何属性和方法)
  2. Array Function Date(日期) Math(数学) RegExp(正则:验证)
  3. Error(错误)
  4. Object(面向对象)
  5. Global(全局对象) ----1、保存着全局变量和全局函数,只不过浏览器端/客户端/前端globa被window代替了 ----2、唯有window对象可以省略不写

周期性定时器

开启:
timer=setInterval(function(){操作;},间隔毫秒数)
停止:
clearInterval(timer);
鼠标的移入和移出事件
onmouseover
onmouseout