JavaScript第一周知识点总结

250 阅读10分钟

一、JavaScript基础

(一)概念

JavaScript简称js是一门运行在浏览器端解释型弱类型面向对象的脚本语言

1. 浏览器端(运行环境):

自带JavaScript解释器(打开浏览器就可以自动运行)

2. 解释型:

执行前不进行编译,直接运行,遇到错误就停止运行

3.弱类型:

变量类型无需定义,根据数据类型决定

4.面向对象:

对象名.属性值; 对象名.方法名();

(二)使用方法

1.直接在HTML页面写

<script>
   代码
 </script>

2.创建js文件,引入HTML页面

 <script src="文件路径">
 **  不可以写代码  **
 </script>

(三)输出方式

1.控制台输出

 console.log(输出内容);//如果输出字符串,使用引号包裹

2.在页面上输出

 document.Write(输出内容);//搭配hover事件会导致替换页面原本内容,不推荐

3.通过警告框输出

 alert(输出内容);//会卡住整个页面,影响用户体验感,不推荐

(四)变量和常量

1.变量

 var 变量名=值;//创建后值可以修改
*变量创建规则
  1.变量名不以数字开头
  2.使用驼峰命名法或下划线命名法
  3.尽量做到见名之意
  4.尽量不使用拼音
  5.变量名不可为关键字
  6.变量名为name时无论是什么类型都默认转为字符串
  7.变量不赋值则默认为undefined,无意义
  8.可以同时定义多个变量(var 变量名1=值1,变量名2=值2;)

2.常量

 const 常量名=值;//创建后不能修改

(五)数据类型

1.原始类型

数据类型名意思数量颜色意义、用法
number数字无数个蓝色直接写
string字符串无数个黑色需要加引号,单双均可
boolean布尔变量两个蓝色只能取true或false,用于条件判断
null一个就是null灰色用于释放变量或内存,提升性能
undefined未被定义一个灰色没有意义

2.引用/对象类型:共11个

3.强制数据类型转换

在隐式转换无法满足需求时使用,页面上一切数据js获取之后都转为字符串类型
undefined和null不能用于做任何操作,因为它们不是对象
   1.转为字符串:
    (1var str=x.toString();
         x的类型不能是undefinednull,会报错
         
    (2var str=String(x);完全等效于隐式转换,还不如+"",不能自己手动使用
    
    
   2.转为数字
    (1parseInt(string/num)   parse:解析  Int:整型
         专门用于将字符串转换为整数,也可以转换其他类型的数字
         执行原理:从左向右依次转换,遇到非数字就停止,不能识别小数点
         
    (2parseFloat(string)     Float:浮点型小数
         专门用于将字符串转换为小数
         执行原理:与parseaInt类似,但是能识别第一个小数点
         
    (3Number(x);完全等效于隐式转换,还不如-0 *1 /1,不能自己手动使用
    
    
   3.转为布尔
     只有 0,"",undefined,NaN,null,false会被转换为false,其他的都是true
     
     Boolean(x);完全等效于隐式转换,还不如!!x,不能自己手动使用
     在分支或者循环条件中,自带此方法
     只要不是以上六个值就是true

(六)运算符

运算符类型运算符特殊点
算数运算符+ - * / %1.%取余,取除不尽的余数
  [1、一般用于判断奇偶(任意数%2)]
  [2、取任何数的后n位(1024%10可以取到41024%100可以取到24)]

2.带有隐式转换,将左右转为数字再进行计算(+除外)
  [null==0]
  [true==1]
  [false==0]
  [undefined==NaN]
  ["10px"==NaN]

3.NaN:Not A Number 是数字类型但不是一个有效数字
  [参与任何算术运算结果都为NaN]
  [参与任何比较运算结果都为false]

4.如果+两边有字符串,则默认将两边都变成字符串,进行拼接
比较/关系运算符> < >= <= == != === !==1.带隐式转换,默认转为数字再比较
2.结果一定是一个布尔值(true或false)
3.如果参与比较的都是字符串,则按位比较每个字符的十六进制unicode号或十进制ACSII码
  [unicode/ASCII的大小:0-9<A-Z<a-z<汉字]
  [汉字第一个字:一,unicode:4e00,ASCII:19968]
  [汉字最后一个字:龥,unicode:9fa5,ASCII:40869]

4.NaN参与任何比较结果都是false,即使是两个NaN进行比较
5.===表示全等,数据类型和值都相等才是全等
6.!==不带隐式转换的不等比较
  [undefined==null,undefined!==null(值相等但类型不同)]
赋值运算符= += -= *= /= %=1.=表示赋值,将右边的值保存到左边的变量名中
2.剩下的表示运算后再将值保存到变量名下
  [i+=1 <==> i=i+1]
逻辑运算符与或非1.是一种综合比较,结果一定是一个布尔值
2.与,全部条件满足则为true,一个条件不满足就false
3.或,一个满足就为true,全都不满足则为false
4.非,改变其布尔值,!true表示false
自增自减运算符++ --1.自增,++,固定每次+1
2.自减,--,固定每次-1
3.++i和i++的区别
  [单独使用没有区别]
  [参与其他运算时,变量本身+1,但返回结果不同]
  [++i返回加后的新值]
  [i++返回加之前的旧值]

二、程序的流程控制语句

(一)顺序结构

 默认从上向下执行

(二)分支结构

做判断时使用
1.if...else
   语法:
    (1)一个条件,一种操作   
          if(条件){
             操作;
             }
             
    (2)一个条件,两种操作
          if(条件){
             操作1:;
             }else{
             操作2;                
             }
             
    (三)多个条件,多种操作
          if(条件1){
            操作1;      //分支选择一种执行,条件应该从严格向宽松写
            }else(条件2){
            操作2;
            }else{
            操作三
            }
         
            
2.switch
   语法:
     switch(变量/表达式){
           case1:        //中间多个case值操作相同时可以省略中间部分
             操作1;         //如:
             break;         //case 值1:
           case2:        //case 值2:
             操作2;         //case 值3:
             break;        //case 值4:
           case3:       //操作;
             操作3;        //break;
             break;
           default:      //default后边可以省略break
             默认操作;
     }
     
     
 3.三目运算:可以简化分支
    语法:
      条件?操作:默认操作     等价于     if...else...
      条件1?操作1:条件2?操作2:默认操作   等价于    if...else if... else...
      
    ps: 默认操作省略了会报错,操作语句大于一句就不能使用三目运算
    

面试题1:if...else和switch...case的区别是什么?

 答: if...else:
        优点:可以进行范围判断
        缺点:执行效率低,速度慢
      
     switch...case:
        优点:执行效率高,速度快,进行比较时,case做的是等值比较
        缺点:使用之前必须知道结果

(三)循环结构

反复执行相同或者相似操作时使用
执行原理:创造循环变量,判断条件,满足则执行循环体,不满足退出循环
1.while
      语法: 
         var 循环变量= ;         //如:  var i=1
         while(循环条件){        //      while(i<4){
           循环体;               //        console.log(i);
           循环变量的变化;        //        i+1;
         }                       //      }
       特殊:死循环:while(true/1){循环体}   
                    1.不确定循环次数时使用
                    2.搭配break,退出整个循环
                    3.搭配continue,退出本循环,但会执行下一次循环
         
2.for
      语法:
         for(循环变量;循环条件;循环变量的变化){        //如:   for(var i=1;i<4;i++){
            循环体;                                  //          console.log(i);    
         }                                          //           }
      特殊:死循环:for(;;){循环体}
         
         
3.do...while
      语法:
         var 循环变量= ;
         do{
            循环体;
            循环变量的变化;
         }while(循环条件)

面试题2:while和for的区别是什么?

  答:原理上几乎没有区别
      在不确定循环次数时常使用while-----死循环
      确定循环次数时则更倾向于使用for---更常用
      

面试题3:while和do...while的区别是什么?

  答:第一次执行时如果条件都满足则无差别
     条件不满足时,while不执行,但do...while至少执行一次

(四)fanction---函数

概念:function是函数,又叫方法,指的是预定义之后可以反复使用的代码段,函数名其实就是一个变量名

1.函数的使用方法

  1.创建/声明/定义函数
       (1)使用声明方式创建
             function 函数名(形参列表){
                 操作;
                 return 返回值/结果;
                 }
       (2)使用直接量方式创建
             var 函数名=function (形参列表){
                 操作;
                 return 返回值/结果;
             }
             
  2.调用函数
       (1)在js内部:函数名(实参列表);
       (2)在HTML页面绑定事件:<标签名 on事件名="函数名(实参列表)">
       (3)通过var 变量名=函数名(实参列表);来保存函数返回值/结果
        
  3.特殊点:
       (1return的本意是退出函数,在return后边加上数据就可以将该数据返回到函数作用域外,
        但由于return并不会保存数据,所以需要定义一个变量用于保存函数的返回值
       (2)函数中省略return时,默认return一个undefined

2.作用域

  1.全局作用域:
      可以定义全局变量、全局函数,它们可以在页面上任意位置使用
      
  2.函数作用域:
      可以定义局部变量、局部函数,在函数被调用时,在函数内部使用
      
  3.变量使用规则:
      函数执行时优先使用局部变量,没有则使用全局变量,都没有就报错
      
  4.特殊:
      (1)在函数中向未声明的变量赋值就会导致全局污染
             也就是全局作用没有声明的变量,被函数作用域添加上了
             
      (2)局部作用域可以直接使用全局变量、函数,全局作用域则必须通过保存return的值才
      能使用局部变量,局部函数只在定义它的函数被调用的时候执行
      
  5.声明提前:
      规则:在程序正式执行之前,将var声明的变量/函数名提前到当前作用域顶部,赋值/函数值
      则不动,function声明的函数整个提前

3.重载

 1.概念:相同的函数名,根据传入实参的不同,执行不完全相同的操作
 
 2.使用方法:
     在函数内部使用对象argument(类数组对象),无需定义,不写形参也可以接收实参,
     默认argument.length=0
     
 3.固定搭配:
    (1)通过下标获取实参:argument[i],i从0开始
    (2)通过length获取实参的数量
    
 4.原理:
     通过判断传入实参的数量,执行不同操作,变相实现重载

5.数组基础

  1.创建方式:2种
     (1)直接量方式
              var arr=[];//空数组
              var arr=[数据1, 数据2..., 数据n];
     (2)构造函数方式
              如果使用此方法,在括号里写一个数字,会默认创建一个长度为该数字的空数组
              ,数据是undefined
              var arr=new Array();//空数组
              var arr=new Array(数据1, 数据2..., 数据n);
              
  2.使用方式:
     (1)获取数组中的元素:
              数组名[i]//获取数组中编号为i的元素
     (2)后续添加/替换元素:
              数组名[i]="新数据";
              
  3.数组特点:
     (1)不限制元素类型
     (2)不限制元素长度
     (3)不限制下标越界
   
  4.下标越界的坏处:
     (1)获取时下标越界会返回undefined
     (2)添加时越界,得到稀疏数组,在遍历时会得到很多undefined
  
  5.避免下标越界的方法:使用arr.length
  
  6.固定用法:
     (1)向末尾添加:arr[arr.length]="新数据";
     (2)获取倒数第n个元素:arr[arr.length-n];
     (3)缩容---删除倒数第n个元素:arr.length-=n;
     (4)遍历数组:for(var i=0;i<arr.length;i++){arr[i];}

(五)DOM(Document Object Model)

意为文档对象类型 专门用于操作HTML对象

原本DOM是可以操作一切结构化文档的,但是再某一次升级后,为了方便各类程序员将DOM分为了3方面:

1、核心DOM:即可以操作HTML又可以操作XML,但是语法相对比较繁琐
    
2HTML DOM:只可以操作HTML,不能访问一切自定义的东西,但语法简单
    
3、XML DOM:只可以操作XML已经被JSON数据格式代替了

1.DOM树的概念:DOM将HTML视作倒挂的树状结构,但是树根是document而非html

 document对象:无需创建,js解释器自动创建,一个页面只有一个
 
 作用:可以通过树根找到想要的任何一个DOM元素/节点/对象(属性和方法)

2.查找元素

    (1)通过id查找
         var elem = document.getElementById("id值");
         特殊:
           返回值:找到就返回DOM元素,没找到就返回null
           出现多个相同的id,只会找到第一个
           前端开发不使用id查找
         
    (2)通过标签名查找
         var elem = document/已经找到的父元素.getElementByTagName("标签名");
         特殊:
           返回值:找到返回一个类数组DOM集合,没找到就返回空集合
           js只能操作DOM元素,不能直接操作DOM集合
           使用已经找到的父元素对标签名的查找会更准确
           
    (3)通过class名查找
          var elem = document/已经找到的父元素.getElementByClassName("class名");
         特殊:
           返回值:找到返回一个类数组DOM集合,没找到就返回空集合
           js只能操作DOM元素,不能直接操作DOM集合
           使用已经找到的父元素对标签名的查找会更准确
           
    (4) querySelector: 查询css选择器 query(查询)
         1.var elem = document.querySelector("任意css选择器");
         缺陷:只能找到单个元素,如果匹配到了多个,也只会返回第一个,没找到null
					
         2.var elem = document.querySelectorAll("任意css选择器");
         优点:
                  1、找到了是一个集合,没找到是一个空集
                  2、进行复杂查找时,简化了操作
                  3、返回的是一个静态集合NodeList
                  

面试题:

  1.document.getXXXdocument.queryXX
      答:后者更适合复杂查找
			
  2、动态集合和静态集合的区别?
  答:
         1、动态集合:每一次DOM发生变化时都会再次查找,让页面和数据保持一致,
         因此效率更低 - 不支持forEach
         2、静态集合:每一次DOM发生变化时不会再次查找,没有让页面和数据保持一致,
         因此效率更高 - 支持使用forEach

3.通过关系查找元素,前提:找到一个元素后才可使用关系

会返回一个动态集合HTMLCollection
关系语句范围
父元素elem.parentNode单个元素
子元素elem.children集合
第一个子元素elem.firstElementChild单个元素
最后一个子元素elem.lastElementChild单个元素
前一个兄弟elem.previousElementSibling单个元素
后一个兄弟elem.nextElementSibling单个元素

4.操作元素,前提:找到元素

 1.内容
 elem.innerHTML(会显示子元素标签)
    获取和设置开始标签到结束标签之间的内容,有标签的话就会显示标签
    获取:elem.innerHTML;
    设置:elem.innerHTML="新内容";
    
 elem.innerText(不显示子元素标签)
    获取和设置开始标签到结束标签之间的纯文本
    获取:elem.innerText;
    设置:elem.innerText="新内容";
    
 input.value: 专门获取/设置input里的内容
    获取:input.value;
    设置:input.value="新内容";
    
  2.属性:
      *****设置属性为空字符串,对于某些属性可以算是删除,但只删除了属性值,属性名还在,
           有的属性只有一个属性名,也会有作用(如: href属性值为空会刷新界面,
           disabled,readonly,checked这类属性,原本就可以省略属性值)
           
    (1)核心DOM:
        获取属性值:elem.getAttribute("属性名");
        设置属性值:elem.getAttribute("属性名","属性值");
        删除属性值: elem.removeAttribute("属性名");
   
    (2)简化版(HTML DOM):
        获取属性值:elem.属性名;
        设置属性值:elem.属性名="属性值";
        删除属性值: elem.属性名=""; - 属性节点删不干净
        特殊点:
         class必须写作className----ES6(2015年)class变成了关键字
         不能操作自定义属性
  
  3.样式:
    a.内联样式
     (1)优点:不牵一发而动全身,优先级最高
     (2)获取样式:elem.style.css属性名;
     (3)设置样式:elem.style.css属性名="css属性值";
     本方法只能获取和设置内联样式
     (4)特殊:css属性名之前使用横杠链接的地方,变为小驼峰
               如:border-radius----borderRadius
               
    b.样式表样式
         var sheet=document.styleSheets[i]; //获取想要操作的样式表
         var rules=sheet.cssRules;//获取此样式表中所有的样式规则
         var rule=rules[i];//数出想操作的规则的下标
         console.log(rule.style.css属性名);
         rule.style.css属性名="css属性值";//操作
        
   4.判断是否有某属性,只能判断有没有,不能判断是什么,推荐用elem.getAttribute("属性名");
   获取到值后自己再写比较运算(返回true/false)
        核心DOM:elem.hasAttribute("属性名");
        HTML DOM:elem.属性名!="";

  ******优先使用HTML DOM,实现不了的再用核心DOM补充

6.绑定事件的三种方式:

1、在HTML上书写事件属性
	<elem on事件名="函数名(实参)"></elem>
	缺点:
		1、不符合内容与样式与行为的分离原则
		2、无法动态绑定,一次只能绑定一个元素
		3、不支持绑定多个函数对象

2、*在js中使用事件处理函数属性
	elem.on事件名=function(){
              操作;
            }
	    优点:
		1、符合内容与样式与行为的分离原则
		2、动态绑定,一次能绑定多个元素
	    缺点:
		不支持绑定多个函数对象

3、*在js中使用事件API:如果不用考虑IE,那也不错
	主流:elem.addEventListener("事件名",callback);
	IE:elem.attachEvent("on事件名",callback);
            优点:
		1、符合内容与样式与行为的分离原则
		2、动态绑定
		3、支持绑定多个函数对象
	    缺点:有兼容性问题

	兼容的写法:
		if(elem.addEventListener){
			elem.addEventListener("事件名",callback);
		}else{
			elem.attachEvent("on事件名",callback);
		}

     

7.创建元素及上树的步骤:

   1、创建空标签:
      var elem=document.createElement("标签名");
          
   2、为其设置必要的属性和事件
          elem.属性名="属性值";
          elem.on事件名=function(){}
          
   3、上树:3种
          *父元素.appendChild(elem);//在父元素末尾处追加一个子元素elem
          
          父元素.insertBefore(elem,已有子元素);
          //在父元素追加一个子元素elem,但是放在已有子元素的前面
          
          父元素.replaceChild(elem,已有子元素);
          //在父元素追加一个子元素elem,但是会替换掉已有子元素
          
  *** 4.1select&option专用创建元素&上树语句:
	select.add(new Option("innerHTML","value"));

8.删除元素:elem.remove();

9.拓展:

  1、创建变量:新增的一个let关键字:

   let 变量名=值;
       作用:
                1、解决了声明提前
                2、带来了块级作用域,一个{}就是一个块,此变量只能在那个{}里面使用
                3、如果用let去当作下标绑定事件,直接记录着当前元素的下标,不再需要自定义
                下标,forEach的那个形参i就是let创建的
                
2、类数组转为普通数组:接住=Array.from(类数组对象);