JS知识点总结(2)

118 阅读19分钟

数据类型转换

  • 转数值
    1. Number(需要转化的对象) 所有数据类型都可以转换,完全等效于隐式转换
    2. parseInt(需要转化的对象) 字符串和小数转为整数型数字,从左向右依次读取每个字符,碰到非数字字符,就停止转换,如果一来就碰到了不认识的,则为NaN
    3. parseFloat(需要转化的对象) 执行原理同parseInt,可以识别第一个小数点
    4. 隐式转换
      • 算数运算符的隐式转换 X-0 X*1 X/1 X%1 true->1 false->0 undefined->NaN null->0 ''->0
      • 比较运算符的隐式转换(===、!==无隐式转换)
  • 转字符串
    1. String(需要转化的对象) 所有数据类型都可以转换,完全等效于隐式转换
    2. 需要转化的对象.toString() 注意:undefined或null不可用,因为两者都不能使用任何的.操作
    3. 隐式转换
      • 加运算的两边存在字符串时字符串拼接的隐式转换 X+''
  • 转布尔
    1. Boolean(需要转化的对象) 所有数据类型都可以转换,完全等效于隐式转换 注意:除了0、NaN、''、undefined、null、false转化为false;其他都会转化为布尔数据true
    2. 隐式转换
      • 分支/循环的条件之中的隐式转换(只需要判断是否为0、NaN、''、undefined、null、false,否则为true)
      • 逻辑运算符的隐式转换 !!X

所有的隐式转换都出现在运算符之中

js运算符

  • 算数运算符:具有隐式的数值类型转换(当字符串为纯数字的情况下,转为数值类型,如果字符串包含了非数字字符,直接转为NaN) +正常为加法数学运算,当符号任意一边是字符串的时候,就会进行字符串的拼接 -*/%分别是减法、乘法、除法、取余的数学运算 取余运算的运用: 1.判断奇偶性:num%2,结果为0说明是偶数,结果为1说明奇数 2.获取一个数字的倒数n位

  • 比较/关系运算符:在进行比较时具有隐式的数值类型转换(先转成数值类型,再进行比较;结果一定是布尔值)

    • 常规比较: > 大于 < 小于 >= 大于等于 <= 小于等于
    • 特殊比较: == 等于比较 只比较值是否相等,不考虑数据类型 === 全等于比较 值和数据类型都相同 != 不等于比较 !== 不全等于比较 注意:
    1. 如果参与比较的左右两边都是字符串,则是按位PK每个字符的十六进制的unicode号(十进制ascii码) 0-9< A-Z < a-z < 汉字 常识: 汉字的第一个字:一:unicode号:4e00 - ascii:19968;最后一个字:龥(yù):unicode号:9fa5 - ascii:40869; 0-9的ascii:48-57 A-Z的ascii:65-90 a-z的ascii:97-122 获取字符串中第一个字符的ascii码:str.charCodeAt(0)
    2. NaN参与任何比较运算结果都为false,所以没有办法使用普通的比较运算来判断x是不是NaN !isNaN(x);
    3. undefined == null;//true 区分:undefined === null; 全等:=== 要求数值相同,并且数据类型也要相同,不再带有隐式转换 !== 不再带有隐式转换的不全等比较

重写String方法,看出 == 和 === 的区别

function String(x){
 if(x===undefined){
   return "undefined";//return->返回,后面跟着的就是返回的结果
 }else if(x===null){
   return "null";
 }else{
   return x.toString();
 }
}

想要判断多个条件,只能运用逻辑运算符

  • 逻辑运算符:具有隐式的布尔类型转换(左右两边都转为布尔值,再参与判断;结果为布尔值)

    • && 与运算 全部为true,结果为true;一个为false,结果为false
    • || 或运算 全部为false,结果为false;一个为true,结果为true
    • ! 非运算 颠倒布尔值(取反运算)
    • 非布尔值的逻辑运算,会将数值转换为布尔值,然后再运算。但要注意返回的是原值。
      1. &&运算:如果第一个值为true,则返回第二个值。如果第一个值为false,直接返回第一个值
      2. ||运算(找true):如果第一个值为true,则返回第一个值;如果第一个值为false,则返回第二个值
    • 注意:短路逻辑:如果前一个条件,已经可以得出最终结论了,没有必要看后续
      • &&短路:如果前一个条件满足,才执行后一个操作,如果前一个条件不满足,则不管后续操作 目的:简化【简单的】分支:
        1. 一个条件一件事,满足就做,不满足就不做:if(){}
        2. 【简单的】- 操作只能有一句话:多句操作导致我们以后维护项目时观看/阅读代码不方便,往往以后很多操作可能就只有一句话 语法:条件&&(操作);
      • ||短路:实现浏览器兼容性问题:二选一 如:e=e||window.event;
  • 赋值运算符: = 进行赋值操作 += 加等于 例如n1+=3 相当于n1=n1+3 -= 减等于 *= 乘等于 /= 除等于 %= 取余等于

  • 自增自减运算符: ++ 自增:在自身基础上+1 前置++:先改变值,再参与运算 后置++:先参与运算,再改变值 -- 自增:在自身基础上-1 前置-- 后置--

  • 位运算: 左移:m << n,读作m左移了n位,翻译:m*2的n次方 右移:m >> n,读作m右移了n位,翻译:m/2的n次方 缺陷:虽然可以设置指数,但是底数只能固定为2 (更好用的:Math.pow(底数,指数))

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

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

总结: if === &&短路 if...else === 三目运算 if...else if...else === 三目运算 操作多句话使用以上三个 操作一句话使用以上3个

舍入误差

浮点数计算时,由十进制转为二进制运算,其结果再由二进制转为十进制,这个过程中产生数据丢失,即为出现了舍入误差 解决办法1 采用.toFixed(n)方法,四舍五入,保留小数点后n为,消除舍入误差 (建议搭配parseFloat()使用) 解决办法2 将参与计算的小数同乘以相同的倍数,转为整数,再将结果除以该倍数,避免浮点数运算产生的数据丢失

条件分支语句

程序的流程控制语句:3种 1、顺序执行 - 默认,从上向下的依次执行 2、分支结构 - 通过条件的判断,选择部分代码执行 3、循环结构 - 通过条件的判断,选择要不要重复执行某些代码

  • if语句 if(){} 条件满足就执行if的{},不满足不执行 if(){}else{} 条件满足就执行if的{},不满足就执行else的{} if(){}else if(){} 哪一个条件满足就执行哪一个if的{},前面条件满足了,就不考虑后面的条件 if(){}else if(){}else{} 多个条件依次判断是否满足,满足则执行if的{},所有条件都不满足,执行else的{} 在()中书写条件 在{}中书写条件满足时执行的代码

  • switch语句 switch(表达式){ case n1:执行语句1
    break;
    case n2:执行语句2 break; case n3:执行语句3 break; ... default:默认执行语句 }

注:

  1. n1.n2...为表达式的值 case为全等于判断,不带有隐式转换,必须数值和数据类型相同才执行对应语句,不存在隐式转换
  2. break直接跳出当前语句,如果不写break,将向下穿透,无视case条件执行,直至break
  3. 建议:每一个case的操作后都跟上一个break; 有的地方也可以省略break:
    1. 最后的一个操作default可以省略break
    2. 如果中间多个条件,做的操作是一样的,也可以省略掉中间的操作
    3. default可以省略不写,如果条件都不满足的情况,则什么事都不会执行

==面试题:if和switch的比较?==

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

可以利用向下穿透的特性来进行累计计算 例如:累计计算某一天为当年的第几天

    <div>
       <input type="date">
       <p>请选择日期</p>
       <button>点击计算</button>
   </div>
   <script>
       var date = document.getElementsByTagName('input')[0]
       var btn = document.getElementsByTagName("button")[0]
       btn.onclick = function () {
           // console.log(date.value)
           var arr = date.value.split('-');
           //拆解字符串 split
           var year = Number(arr[0]);
           var mouth = Number(arr[1]);
           var day = Number(arr[2]);
           var result = 0;
           switch (mouth) {
               case 12:
                   result += 30;
               case 11:
                   result += 31;
               case 10:
                   result += 30;
               case 9:
                   result += 31;
               case 8:
                   result += 31;
               case 7:
                   result += 30;
               case 6:
                   result += 31;
               case 5:
                   result += 30;
               case 4:
                   result += 31;
               case 3:
                   if(year%4==0&&year%100!=0||year%400==0){
                       result+=29;
                   }
                   else{
                       result+=28;
                   }
               case 2:
                   result += 31;
           }
           result+=day;
           var p=document.getElementsByTagName('p')[0];
           p.innerHTML="这是"+year+"年里的第"+result+"天";
       }
   </script>

循环结构语句

循环结构:反复执行【相同或相似】的操作时使用 循环三要素: 1.循环条件:开始 - 结束,循环的次数 2.循环体:做的操作是什么 3.循环变量:记录着我们当前在哪一次,而且他会不断的变化,往往都会向着不满足循环条件进行

  • while语句 语法: var 循环变量=几; while(循环条件){ 循环体; 循环变量变化; } 执行原理:首先创建了循环变量,然后判断条件,如果条件满足,则做【一次】循环体操作,并不会退出循环,回过头继续判断条件是否满足,如果满足,则再做【一次】循环体操作.直到循环条件不满足,才会退出循环 宏观上感受循环一瞬间就结束了,但是微观上来说其实是【一次一次】执行的
  • do while语句 do{}while(条件) 当初始变量在条件以外时,while语句不执行,do while语句执行一次
  • for语句 语法: for(var 循环变量=几;循环条件;变量的变化){ 循环体; }
  • 注意:
    • 死循环:永远不会停下来的循环 何时使用:不确定循环次数的时候 写法:while(true){循环体;)或for( ; ; ){循环体;}
    • 退出循环语句:
      • break;//退出整个循环
      • continue;//退出本次循环,还会继续接下来的循环
    • 优先使用for循环,不确定循环次数的时候再用while补充

==面试题:while 和 for 的区别?== 语法上有区别,但两者都能做到相同的操作 一般来说我们不确定循环次数的时候,会使用while循环 - 死循环 一般来说我们确定循环次数的时候,就用for循环 - 更漂亮更简洁,大部分情况都会使用它 ==面试题:while和do...while的区别?== 除了写法上有区别,还有一个点:只看第一次 如果第一次大家都满足,两者其实没区别 如果第一次大家都不满足。while一次都不会执行,而do...while至少会执行一次

函数

自定义函数

也叫做方法,是需要预定义好的,以后可以反复使用的代码段

  1. 创建函数并调用

    1. 创建函数(2种方法)
      1. 声明方式创建函数:用关键字function做声明 function 函数名(形参列表){ 函数体; return 返回值; }
      2. 直接量方式创建函数: var 函数名=function(形参列表){ 函数体; return 返回值; } return的本意:退出函数的意思 只不过如果return后面跟着一个数据,会顺便将其返回到全局作用域中,但是只负责返回负责保存! 所以在调用函数时:如果有return,记得拿一个变量接住结果 何时使用:如果你希望拿到函数的结果,以后还要做别的操作,就需要搭配上return var result=函数名(实参列表);
    2. 调用/使用函数:
      1. 要么在js中程序员直接写死,要执行几次:函数名();
      2. 交给用户绑定在某个元素上,写上点击事件,让用户来触发
      • 何时使用:
        1. 不希望打开页面立刻执行,而需要时再使用或由用户触发
        2. 希望能够反复执行,不用刷新页面
        3. 以后任何一个独立的功能体,都要单独封装为一个函数(你的每一个作业)
        4. 函数的地位非常高,函数是第一等公民地位,随时随地考虑能不能封装为一个函数,尤其是重复的代码
        5. 函数内的一切内存,函数调用完毕后都会自动释放
    • 带参数的函数
      • 定义:function 函数名(形参1,形参2,...){ 函数体; }
      • 调用:函数名(实参1,实参2,...)
      • 形参:形式参数,其实就是一个变量,但是不需要写var,而且默认也没有保存任何值,默认值为undefined
      • 实参:实际参数,真正的值,需要再你调用时再传入
      • 注意:
        1. 传实参的顺序一定要和形参的顺序一一对应,并且数量也要对应
        2. 不是一定要带参数的函数才是好函数,具体情况,需要具体分析:
          • 如果函数体就是固定的,则使用普通函数
          • 如果函数体希望根据传入的实参不同,做的略微不同,则使用带有参数的函数
  2. 作用域

    1. 全局作用域:全局变量和全局函数,在任何地方都可以使用
    2. 函数/局部作用域:局部变量和局部函数,在【函数调用时内部可用】 =>变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错
    • 特殊:
      1. 千万不要对着未声明的变量直接赋值:a=1;//会导致全局污染,全局本来没有的东西,突然被添加一坨内存,建议创建变量时,记得一定要写var
      2. 儿子不孝啊:局部的东西全局居然不能用,解决:return↓
      3. 函数没写return或者写了return没有具体的值,默认return undefined
      4. return一般只会出现在函数的最后(之后的代码不执行),而且只能出现一个
      5. 往往前辈们提供的方法,底层都有一个return操作,前辈们觉得以后用这些方法的人,可能还需要拿着这个结果去做别的操作
  3. 声明提前:==笔试重点== 原理: 在程序正式执行之前, 会悄悄地将 var声明的变量 和 function声明的函数, 集中提前到当前作用域的顶部, 变量比函数轻, 但是赋值留在原地 明说: 自己写代码绝对不会碰到,只要我们遵守原则:1.先创建后使用 2.变量名和函数名尽量的不要重复; 只有笔试中碰到,如果你以后碰到先使用在创建,或者经常重复变量名,很有可能就是在考你声明提前; 先转为我们提前后的样子,再去判断;

  4. 按值传递 按值传递:两个变量之间进行赋值

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

  1. 匿名函数

  1. 闭包

预定义全局函数

前辈们提前写好的,我们程序员可以直接使用的,全局(在任何地方都可以使用)

  1. 编码和解码: 问题:url中不允许出现多字节字符,如果出现会乱码 utf-8编码格式下,一个汉字,占3字节 解决:发送前,前端将多字节字符编码为单字节字符(数字、字母) 发送后,后端接住,然后将单字节字符解码为原文 如: 编码:var code=encodeURIComponent("剑风传奇"); 解码:var 原文=decodeURIComponent(code); 其实这个东西在某次浏览器更新后,当前就淘汰了!浏览器现在自带此功能
  2. isFinite(num):判断num是不是无穷大,true->有效数字,false->无穷大 为false的情况:NaN、Infinity、分母为0,此方法不能用来判断是不是NaN
  3. 牛逼的:parseInt/Float()、isNaN()、eval()

.递归函数

function fn(){
   if()return 1;
   return fn(n-1)
}

一个函数调用自身,并设置了结束条件,即为正确的递归函数

.作用域

  • 范围: 全局作用域:一个页面就是一个全局作用域 私有作用域:只有函数 生成私有作用域
  • 使用: 定义:声明在什么位置的变量就是属于哪一个作用域的变量 访问:自己有用自己的,自己没有用父级的,全局没有即报错 赋值:自己有给自己赋值,自己没有给父级赋值,全局没有定义为全局变量

数组数据类型(array)

场景: 当需要保存多个数据时,不推荐使用变量,因为变量其实就是我们所谓的内存,变量创建的越多,那么我们内存空间消耗就越大,那么网站的性能就会越差.这种情况就使用数组.

定义:创建一个变量可以保存【多个数据】的集合 数组都是线性排列,除了第一个元素,每个元素都有唯一的前驱元素 除了最后一个元素,每个元素都有唯一的后继元素 每个元素都有一个自己的位置,称之为叫做下标(索引),下标是从0开始的,到最大长度-1 与对象不同点:不需要键名,自带顺序

创建一个数组 1.直接量方式: var arr=[];//空数组 var arr=[数据1,数据2,...]; 2.构造函数方式: var arr=new Array();//空数组 var arr=new Array(数据1,....);//==笔试考点==:此方法只写一个值的时候为数组长度,即一个定义了数组长度的空数组

数组具有三大不限制:

  1. 不限制元素的个数
  2. 不限制元素的类型
  3. 不限制元素的下标越界 - 不是一个好东西了 如果获取元素,下标越界,返回的一个undefined 如果添加元素,下标越界,会得到一个稀疏数组,导致下标不再连续,如果搭配上循环去遍历每一个元素的话,我们会得到很多很多的undefined

数组的操作

  • 长度的操作
    • 获取长度 arr.length 其值为最大下标+1
    • 设置长度 arr.length=数值 长度小于原数组长度时,会按照顺序删除靠后的数据
    • length的三个固定套路: 1. 获取倒数第n个元素:arr[arr.length-n] 2. 始终向末尾添加元素:arr[arr.length]=新值; 3. 缩容:删除倒数n个元素:arr.length-=n
  • 数据的操作
    • 获取数据 arr[索引值]
    • 设置数据 arr[索引值]=数值 下标处没有元素为添加,有则替换
    • 注意:下标越界
      • 读取数据时,返回undefined
      • 添加元素时,在新位置添加元素=>由于下标的不连续,而产生稀疏数组,稀疏数组遍历得到很多的undefined

数组的遍历 从头到尾依次访问数组的每一个数据即遍历 利用循环进行遍历,开始为0,结束为小于数组长度,步长为1,使用循环控制变量当做数组的索引来访问数组中的每一个数据

for(var i=0;i < arr.length;i++){
   console.log(arr[i])
}

释放一个引用类型的对象:切记一定要看清楚这个对象有几个变量关联着,每个变量都要释放后才能真正的释放. 最好的方式就是封装为一个函数,因为函数中的东西,调用完毕都会自动释放

索引数组:下标都是数字组成的数组(默认) 关联(hash)数组:下标是可以自定义的数组 为什么要自定义下标:索引数组的下标无具体的意义,不便于我们查找

创建关联数组:

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

关联数组的操作:

  1. 访问:arr["自定义下标"];
  2. 遍历:
    • 问题:不能使用for循环去遍历关联数组,因为关联数组的length永远为0,而且下标也不再是数字
    • 解决办法:for in 循环(设置从哪里开始到哪里结束,所有的操作都是自动的,自动获取下标i)
    • 语法:for(var i in 数组名){数组名[i];}
    • 既可以遍历hash数组,也可以遍历索引数组
    • 建议:索引数组依然使用for循环,关联数组再使用for in循环

==JS中除了undefined和null不是一个对象,万物皆对象,而【一切对象的底层都是hash数组】==

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

数组常用方法API

共10个:join、concat、slice、splice、reverse、sort、push、pop、shift、unshift

不修改原数组的API:需要创建新变量接收 1.数组转为字符串 var str=arr.join("自定义连接符");//如果没有传入实参,则和toString效果一致,默认都是用,隔开

  1. ==面试题:完成无缝拼接== var arr=["h","e","l","l","o"," ","w","o","r","l","d"]; console.log(arr.join(""));
  2. 将数组元素拼接为页面元素(==数据渲染==) //获取数据 var arr=["-请选择-","北京","南京","西京","东京","重庆"]; //将数组转为了字符串,并且拼接上了标签 var str="<option>"+arr.join("</option><option>")+"</option>"; //让字符串上DOM树,innerHTML识别标签 sel.innerHTML=str;
  3. 实现二级联动关键点:
    1. 必须使用二维数组,细分每一个城市,并且二维数组的顺序要和之前的一维数组对应
    2. select.onchange=function(){} 状态改变事件:select的专属事件,只有选中项发生变化时,才会触发
    3. select可以直接获取当前选中项的下标,而不需要自定义下标:select.selectedIndex;
    4. 其实绑定事件,等号左边部分就是你的函数名
  4. 返回值:拼接后的字符串

2.拼接数组:添加元素到末尾的新方式 var newArr=arr.concat(值1,arr2....); 注意:

  1. 此方法如果拼接新数组,会打散数组,单个添加
  2. 返回值:拼接后的新数组

3.截取子数组:可能只想拿到数组中的某一部分 var subArr=arr.slice(starti,endi+1); 注意:

  1. 含头不含尾
  2. 只传入一个实参,则为从starti开始,到末尾
  3. 无实参,则复制了一份,即==深拷贝==(两者互不影响)
  4. 支持负数参数,-1代表倒数第一个,-n代表倒数第n个
  5. 返回值:以新数组的形式返回截取的数据

修改原数组的API: 4.删插替: splice:

  • 删除:var dels=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,....); 注意:删除的个数 和 插入的个数不必相同
  • 返回值:以新数组的形式返回删除的数据

5.翻转数组:arr.reverse();//仅仅只能翻转数组顺序

6.数组排序

排序方法

冒泡排序(Bubble Sort) 思路: 1.遍历数组,比较相邻索引的数值大小,将索引靠前的大数值与后面的交换 2.重复多轮

// 定义一个乱序的数组
var arr=[2,1,6,9,4,5,3,8,7]
// 比较length-1轮
for(var j=1;j<arr.length;j++){
   //一轮需要比较length-1-比较轮数 次
   for(var i=0;i<arr.length-j;i++){
       if(arr[i]>arr[i+1]){
           //借助第三个变量,储存将要被重新赋值的数据
           var temp=arr[i+1];
           arr[i+1]=arr[i]
           arr[i]=temp
       }
   }
}
console.log(arr)

选择排序(Select Sort) 思路: 1.先从0开始假定最小数值的索引 2.遍历数组与假定最小数值的比较,得出实际最小的数值的索引 3.将实际最小的数值的索引与假定最小数值的索引交换 4.重复多轮,每轮改变假定最小数值的索引

// 定义一个乱序的数组
var arr=[2,1,6,9,4,5,3,8,7];
// 进行数组长度-1轮的比较
for(var j=0;j<arr.length-1;j++){
   // 假设最小数值的索引为j
   var minindex=j;
   // 循环遍历数组,从索引为1开始
   for(var i=1+j;i<arr.length;i++){
       // 判断是不是比假设索引位置的值小
       if(arr[i]<arr[minindex]){
           // 如果为true,替换最小数值的索引
           minindex=i
       }
   }
   // 交换假设的最小数值的索引和真实的最小数值的索引
   var temp=arr[j];
   arr[j]=arr[minindex];
   arr[minindex]=temp;
}
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的底层就是通过返回的值来判断是否交换位置
    • 降序:arr.sort(function(){return b-a;})

==以后网页中见到任何带有排序功能的特效,说明它的底层一定是数组,因为JS中只有数组可以排序,先排序再数据渲染==

7.栈和队列

  • 栈:一端封闭,只能从另一端进出.使用场景:希望使用到最新的数据的时候
  • 队列:只能一端进入,另一端出.使用场景:按照先来后到的顺序
  • 作用:添加元素和删除元素的新方式

栈:

  • 开头入: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();

pop和shift返回值为删除的数据,push和unshift返回值为最新的数组长度

二维数组

释义:数组的元素,又一次引用了一个数组 使用场景:在一个数组内再次细分分类

创建二维数组: var nums=[ [1,2,3], [4,5,6], [7,8,9] ];

访问二维数组的元素:arr[r][c] - r代表行下标,c代表列下标 注意:

  1. 列下标越界,返回undefined
  2. 行下标越界,返回报错,(行下标越界已经得到undefined再加[]则报错)

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

字符串(String)

String的基础概念 什么是字符串:多个字符组成的【只读】字符【数组】

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

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

  • String、Number、Boolean -> 包装类型
  • Array、Function、Date(日期)、Math(数学)、RegExp(正则:验证)
  • Error(错误)
  • Object(面向对象)
  • Global(全局对象)
    1. 保存着全局变量和全局函数,只不过浏览器端/客户端/前端global被window代替了,在Node.js后端语言中全局真的是global
    2. 唯独window对象可以省略不写

包装类型:专门封装原始类型的值,将原始类型悄悄的变成了引用类型的对象(从而具有了属性,并可使用方法) 本身原始类型的值,不带有任何属性和方法,意味着不能使用.去做操作的 何时使用:只要你试图使用.去操作原始类型的值的时候,包装类型就会悄悄出现 何时释放:方法一旦调用结束,包装类型就会自动释放 注意:undefined和null没有提供过包装类型,因此两者没有任何属性和方法,不饿能使用.操作

扩展: 周期性定时器:

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