JavaScript基础知识点总结

时间:2023-03-08 15:35:24

JavaScript----js

全栈课程-------全栈工程师

前端:信息展示,普通用户浏览---前端工程师(html+css:静态页面 js:页面的交互效果)

后台:信息管理,管理员,数据库------后端工程师(php+mysql)动态页面

产品上线,部署

特别注意:

1.每条js语句结束都需要写英文状态下的;

2.js所有的标点都是英文状态下的

3.单双引号的问题:进行字符串的定义或者输出,单双引号的内容可以原样输出,互相嵌套

js的历史

  • 网景公司:Navigator浏览器0.9版本【1994】

  • sun公司:javascript

  • js之父:Brendan Eich--10就发明了js

  • ESMAScript组织规范js的语法

理解(抄笔记、敲代码)+记忆

js的作用

  1. 实现网页的交互作用

  2. 进行数据验证

  3. 操作cookie、session

  4. 小游戏:贪吃蛇、打字游戏、扫雷

  5. 与后台的node.js

  6. ......

js的组成

ECMAScript------js的基础语法

BOM------Broswer Object Model 浏览器对象模型

DOm----Document object Model 文档对象模型

js的特点

基于对象和事件驱动的松散型、解释性语言,寄宿于浏览器,单线程异步

JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言内置支持类型,他的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,用来给html网页增加动态功能。

js的报错

  1. 语法错误:Uncaught SyntaxError

    低级错误,执行前全部扫描一遍,如果有语法错误,所有js代码错误,所有js代码都不执行

  2. 逻辑错误:

    在js代码执行时发生,不可避免,出错的代码不会执行,之前的代码会正常执行

js的引入

注意:外部引入和嵌入式不能混合使用,一个srcipr中不能既有src又有js代码,但可以有多个srcipt标签共同作用

  1. 外部引入

    <srcipt src="js/index.js"></srcipt>
  2. 嵌入式

    <srcipt>直接写js代码</srcipt>
  3. 在a的href中

    <a href="javasrcipt:alert('1')">我是a</a>
  4. form表单

  5. 事件后面

    <div class="box" onclik="alert('1')">
    []\]
    </div>

js的调试工具

  1. alert()------窗口弹出框

  2. console.log()--------在控制台输出

  3. document.write()-------写入的页面(可以识别标签)

  4. prompt()-----输出弹框

  5. confirm()----确认取消框

变量

可以变化的量。数据存储的容器

  1. 变量的声明

    • 声明变量,用关键字var

    • 没有用var声明的变量,叫全局变量

    • 不要用var多次声明同一个变量

    • 变量提升:一个变量先使用后赋值,默认为undefined(变量提升)

    • js执行时浏览器会进行预解析,var声明的变量以及function函数会进行变量提升

  2. 变量的赋值

    • 可以在声明的同时赋值

      var num = 1;
    • 可以先声明,后赋值

      var num1,
      num1 = 1;    
    • 一次性声明多个变量(用,隔开),然后分别赋值

      var num2,num3;num2 = "123"; num3 = "123";
    • 一次性声明多个变量的同时赋值

      var num4 = 1, num5 = 2;
    • 可以多次赋值,后面的会覆盖前面的

    • 一个变量没有声明就使用,会报错(该变量 is not defined)

    • 未赋值的变量默认为undefined

    3.变量命名时注意的:

    • 名字都是以数字、下划线、字母与$组成,数字不能开头

    • 常用的命名方式:要有意义,见名知意(英文翻译)、驼峰命名法、首字母大写

    • 避免与关键字与保留字冲突

    • 区分大小写:

数据类型

初始数据类型和引用数据类型的区别:分别放在栈区和堆区,栈区和堆区的区别:栈区放置变量和函数名,执行完程序自动删除,堆区放置引用的数据,可以自己删除,也会被js的垃圾回收处理删除

初始数据类型

  1. 数值型-----typeof:number

    • 整数

    • 小数

    • 负数

    • 科学计数法(3.2e5)

    • 二进制0b开头、八进制0开头、十进制、十六进制0x开头

    • 最大值(Number MAX_VALUE)

    • 最小值(Number MIN_VALUE)

    • parseint 从首位开始转化为整型。,如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN 123a456 转换成123

      ​ null\undefined/bolen--->NaN

    • NaN (not a number)-----不是一个数 Nan==NaN (false) Number.isNAN(NaN)

      if(Number.isNAN(num) 如果number是NaN。返回true

  2. 字符串--------typeof:String

    单双引号里面的内容,双引号里面嵌套单引号,单引号里面嵌套双引号

    • 数值型字符串

      var str2 = "12234";
    • 非数值型字符串

      var str = "abcdef";
      var str1 = "cdes'qwe'qq";
  3. 布尔值--------typeof:Boolean

    var b = false;
    var c = true;
  4. undefined--------typeof:undefined

    未定义----只声明未赋值的变量默认是undefined,先使用后声明的变量为undefined

    var cc;
    console.log(cc)//undefined
    console.log(dd)//undefined
    var dd = 10;
  5. null--------typeof:Object

    清空对象

复合数据类型

  1. 对象/object--------typeof:Object

    ​ 函数、数组

运算符

算数运算符

  1. 算数加: 算数加/字符串拼接

    • !!任何数据类型与字符串相加,结果都是字符串

  2. / * -

    • 算数的减乘除,得到的结果一定是number类型

    • 如果不能运算(字符串/字符串),得到的结果为NaN

    • 如果是数值型字符串,会默认转化为数值型

  3. % 取余得到的结果

  4. ++/-- 自增

    • 如果++/--在前,先自增再运算

    • 如果++/--在后,先运算后自增

关系运算符----得到的结果为布尔值

​ <= < > >= == != === !==

  • 数值型与数值型比较,直接比大小

  • 数值型与非数值型字符串比较,不能比较大小,直接返回false

  • 数值型与数值型字符串比较,先把数值型字符串转化为数值型,再依次比较大小

  • 字符串与字符串比较,依次比较ASCll码的大小

  • == === != !==

    • == 判断数值是否相等

    • === 判断数值与数据类型相等

    PS:= 赋值运算

赋值运算符

= += -= *= /= %=

逻辑运算符

  • && 逻辑与

    • 当所有表达式都为真时,结果为真;只要一个为假,结果为假

  • || 逻辑或

    • 只要一个为真,结果为真;所有表达式为假,结果为假

  • ! 逻辑非

    • 取反,原来表达式为真,结果为假;原来表达式为假,结果为真

特殊的几个假值:0 NaN false undefined "" null

======================================================================

赋值时,会发生短路运算:

&&会找第一个假值,如果没有会找第二真值;

||会找第一个真值,如果没有会找第二假值

运算符的优先级

let x,y,z

x=1+3<2|| true 输出为true || 小于 = 小于 < 小于 +

=======================================================================

表达式1 表达式2 && ||
true true true true false
true false false true flase
false false false false true
false true false true true

三元运算符

一元运算符:+(正数) -(负数) ++(自增) --(自减) new实例化对象 delete删除对象属性或变量

(表达式1)?(表达式2):(表达式3)

如果表达式1成立,执行表达式2,否则,执行表达式3

特殊运算符

  • ,声明多个变量的时候进行分隔

  • () ---- 提高运算的优先级/函数调用

  • \转义

=====================================================

运算的优先级:

赋值运算优先级最低,()优先级最高

赋值运算时,从左往右的顺序执行

其他运算,从左往右的顺序执行

====================================================

流程控制

代码执行的顺序

1.顺序结构

按照顺序依次执行

2.分支结构/选择结构

  • 单路分支

    if(条件表达式){
    //条件成立要执行的语句
    }
  • 双路分支

    if(条件表达式){
       条件成立要执行的代码
    }else{
       条件不成立要执行的代码
    }    
  • 多路分支

    if(条件表达式1){
       执行语句1
    }else if(条件表达式2){
       执行语句2
    }else if(条件表达式2){
       执行语句2
    }else{
       以上条件不成立,输出的语句
    }
  • 嵌套分支

    if(表达式1){
       if(表达式){
           执行语句1;
      }else{
            执行语句2;
      }
    }
  • switch分支

    // switch(表达式){
    // case "表达式可能的值":如果是该值要执行的语句;
    // break(终止后面程序的执行)
    // }
    //案例1:测试星期几
    var week = prompt("亲输入内容");
    switch(week){
    case "1":alert("星期一");
    break;
    case "2":alert("星期二");
    break;
    case "3":alert("星期三");
    break;
    case "4":alert("星期四");
    break;
    case "5":alert("星期五");
    break;
    case "6":alert("星期六");
    break;
    case "7":alert("星期日");
    break;//终止,结束
    //其余所有情况都不满足时要执行的代码
    default:alert("输入错误")
    }

    if和switch的不同点:

    • if是连续性数据的区间

    • switch是离散型数据

  • if(括号里可以写)

    • 条件表达式

    • number 除了0以外都是true 0是falsestring “”空字符串是false,其他都是true

    • undefined/null在转换下会变成NaN

    • bolean true/ false

3.循环结构

  • for循环

    for (var i = 0; i < 10; i++) {
    //循环体
    console.log(i)
    }
    //语法
    for(表达式1;表达式2;表达式3){
    循环体
    }
    表达式1:变量的初始值
    表达式2:进行循环的条件 i<10
    表达式3:步进值 i++/i--
    // 执行过程:
    表达式1--->表达式2(判断是否满足当前的条件)--->如果满足,执行循环体--->表达式3(让变量自增)如果     不满足,直接跳出循环体
  • while循环

    当条件满足时,在进入循环体

    适用于:只知道循环的条件,不知道要循环几次

    var num = 6;
    while(num<10){
    console.log(1)
    num++;
    }
  • do while循环

    先执行循环体,在判断条件是否满足

    不管条件是否满足,总会先执行一次循环体

    适用于:只知道循环的条件,不知道循环的次数

    do while{
      //循环体
    }(条件)

数组:可以存储一组或一系列相关变量的容器

应用场景:

​ 解决大量相关数据的存储

​ 便于程序的开发和使用

清空数组:arr.length=0

注意事项:可以存储任何数据类型的数据
长度可变
数组下标从0开始,如果指定长度没有赋值则输出undefined

定义数组:直接赋值/先声明后赋值

var arr = [];
var newarr = new Array(里面的是数组的长度);new一个实例化对象
//数组中可以存储任何数据类型的数据如下:
var arr = [1,"234",undefined,null,false,[]];

访问数组

访问数组用下标,从0开始

可以越界访问,越界访问的值默认为undefined

自定义数组的长度,未赋值的位置为undefined

数组的长度,arr.length

与下标的关系:比下标多一

数组的遍历---得到数组的每一个元素

for of更加适合遍历数组,遍历的是数组的value,不能遍历对象

for in 更适合遍历对象 ,遍历的是数组的index

1.一维数组

let arr1=[1,2,3]

let arr2

arr2=arr 直接赋值这叫传址 ar r1再次发生变化 arr2 也变化

遍历赋值 叫做浅拷贝 arr1变化 不影响arr2

var arr5=["fas",23, 45,"asd"];
for(var i=0;i<arr.length;i++){
console.log(arr5[i]);
}

2.二维数组的遍历

浅拷贝是一个传址,也就是把a的值赋给b的时候同时也把a的址赋给了b,当b(a)的值改变的时候,a(b)的值同时也会改变

深拷贝:深拷贝是指,拷贝对象的具体内容,二内存地址是自主分配的,拷贝结束之后俩个对象虽然存的值是一样的,但是内存地址不一样,俩个对象页互相不影响,互不干涉

外循环控制的是二维数组的长度,其实就是一维数组的个数行数。

内循环控制的是一维数组的长度,每一行,一维数组元素分别的个数。

    // 求二维数组所有元素的和
var arr9 = [[1,1],[1,1],[1,1]];
function arr(arr1){
var plus=0;
for (var i = 0; i < arr1.length; i++) {
for (var j = 0; j < arr1[i].length; j++) {
plus +=arr9[i][j];
}
}
return plus;
}
console.log(arr(arr9))

for(let i in arr9){
   console.log(i);
   console.log(arr9[i])
}

//forEach
let res = arr9.forEach(function(val,index){
   console.log(val,index)
})


let res = arr9.forEach(function(val,index)=>{
   console.log(val,index)
})

函数

函数的作用

封装具有特定功能的代码段,代码段可以重复使用

函数的定义:封装具有特定功能的代码段,代码段可以重复使用

  • 用function关键字定义--会优先解析,可以声明之前调用函数

    形参:形式参数,在声明函数时括号里面的参数 作用 :接收实参

    实参:实际参数,在调用函数时括号里面的参数 作用:传递参数

    参数问题:1.参数可以是任何的数据类型

    ​ 2、参数的个数(默认要一一对应)

    ​ 如果形参>实参,剩余形参为undefined

    ​ 如果实参>形参,剩余实参可以在arguments对象中寻找

    function funName(形参1,形参2,...){
       //里面写函数体
    return;
    }   funname(实参1,实参2)
  • 通过字面量的函数,匿名函数--只能先定义后调用,不能再定义之前调用,否则,会报错

     var a=function(){
    //函数体
    return;;
    }a()
    匿名函数
    (function(){
        console.log(123)
    })()  
  • 通过实例化Function得到一个函数

    var fn = new Function("形参","函数体")      

    fn()

函数的调用--

  1. 函数名();

  2. 写在事件中

  3. 自调用

    (function aa(){
       alert(num)
    })(2);

函数的参数

可以让函数更加灵活

  • 形参:定义函数时()中的的参数,相当于变量名

  • 实参:调用时函数里面的参数,相当于变量值

  • 函数的重载:通过参数的类型或值得不同,执行不同的函数体

  • 关系

    ​ 实参=形参:--对应

    ​ 实参<形参:多余的形参默认是undefined

    ​ 实参>形参:多余的实参用arguments处理

    ​ 也可以...res接受

    ​ arguments:每个函数都有的属性,用来接收所有的的实参,把实参放在类似于数组的对象中

    ​ ...res:接受多余的实参,放在一个数组中

    ​ function aa(num,num1,...num2){

    console.log(num,num1,num2)//1 2 (9) [3, 5, 8, 9, 2, 45, 5, 5, 5]

    ​ }

    ​ aa(1,2,3,5,8,9,2,45,5,5,5)

  • 参数的默认值

    • if else

      function fn(num,flag){
         if(flag==undefined){
             flag="+";
        }else{
             flag=flag;
        }
         if(flag=="<"){
             //从大到小排序
        }else if(flag==">"){
             //从小往大排序
        }
             
      }
    • 三元表达式

      flag = (flag==undefined)?("+"):(flag)
    • 逻辑表达式

      flag = flag||"+";
    • ES6中,直接写在形参的最后,如果该值为假,才会促发

      function fu(num,flag="+“){
      //函数体
      }

函数的返回值

  • 作用:

    • 终止函数的运行

    • 给函数一个返回值

  • 可以返回任何数据类型的数据,函数返回的结果是调用函数的结果

  • 每个函数都只能有一个返回值,如果有多个,就是在分支结构中

  • 原则上,每个函数都有一个返回值,如果没有,调用函数的结果undefined

作用域

全局作用域/全局变量:

  • 在全局或任何地方都可以起作用的变量,任何地方都可以修改

  • 通过var在外部定义的变量

  • 没有用var声明但赋值的变量

局部作用域/局部变量:

  • 定义在函数内部的变量

  • 函数的形参

  • 用let声明的块级作用域的变量

块级作用域:{}

作用域链:

我们可以把作用域看成是用链条连接起来的,这样能够使得函数能有序的进行运行

里层函数可以访问外层函数的变量,但是外层函数不可以访问里层函数的变量

几种特殊函数

递归函数

自己调用函数

案例

1.深拷贝

2阶乘:1的阶乘为1 0的阶乘为1

//阶乘 5! = 5*4*3*2*1         
// 5! = 5*4!
//   4*3!=24
//     3*2!=6
//       2*1!=2
//       1!=1
//       0!=1
//找规律n! = n*(n-1)!
//找界定条件 0!=1 1!=1
function jc(num){
if(num == 1||num == 0){
return 1;
}
return num*jc(num-1);
}
alert(jc(6))

斐波纳契数列 fb(num-1)+fb(num-2)的阶乘为1

F(n)=F(n-1)+F(n-2)
F(5)=F(4)+F(3) 5
F(4)=F(3)+F(2) 3
F(3)=F(2)+F(1) 2 function fb(num){
if(num == 1||num==2){
return 1;
}
return fb(num-1)+fb(num-2);
}
alert(fb(10))

回调函数--作为参数的函数

function main(num1,num2,collback){
console.log("我是主函数")
collback();
return num1+num2;
}
function fn(){
console.log("我是回调函数");
}
let arr = [1,2,3];
main(1,2,fn)
四则运算
function jia(a,b){
   return a+b;
}
function jian(a,b){
   return a-b;
}
function cheng(a,b){
   return a*b;
}
function chu(a,b){
   return a/b;
}
function fnn(a,b,fn){
   return fn(a,b)
}
console.log(fnn(10,30,cheng))
高阶参数
//num的阶乘

function fn(num){
   if(num==0){
       return 1;
  }
   if(num==1){
       return 1;
  }
   else{
       return num*fn(num-1)
  }
}
console.log(fn(5))

//数组 深拷贝
let  arr=[[1,2],[5,8],[1,[8,77,[99,33]]]];
function aa(arr){
   for(let i=0;i<arr.length;i++){
       if(typeof arr[i]!="object"){
           newarr[i]=arr[i]
      }else{
           newarr[i]=aa(arr[i])
      }
  }
   return newarr
}
console.log(arr)

闭包函数

定义:当两个函数发生嵌套关系时,内层函数使用外层函数的变量,并在全局环境下调用内层函数 保护内部变量不别清理掉

箭头函数--ES6新增的函数的表现形式

1.形参=>返回值

let sum = num=>num;
console.log(sum(1))

2.(形参1,形参2)=>返回值

 //(形参)=>返回值
let sum=(num,num1)=>num+num1;
console.log(sum(1,2))

3.(形参1,形参2)=>{​ 函数体;​ return;}

let fu = (num1,num)=>{
   if(num1%2=0){
       num1=1;
  }
   return;
}

内置顶层函数

ECMAscript 自带的函数,ECMAscript将我们常用的一些功能封装起来,我们不需要知道他是怎么实现

的,只需要知道怎么调用即可。.js内部定义的,在任何地方可以调用的函数

  1. escape() 将非字母、数字字符进行编码

  2. unescape() 对编码的字符串进行解码

  3. Number() 转换成数值类型

    • 布尔值-->false--0 true---1 字符串:数值型的字符串---直接转换 非数值字符串---NaN

    • undefined-->NaNnull--->0

  4. String() 转换成字符串类型

  5. Boolean() 转换成布尔类型

    • null、undefined、0、""、NaN 、false为假,其他都为真

  6. !!!!!!!parseInt() 将字符串转换为整型

  7. parseFloat() 转换为浮点数数:去掉一些没有意义的0

  8. tofixed(n)给数字后面加小数点后位数

    let num=12 ; console.log(num.toFixed(2))---12.00

  9. isNaN() 判断是不是NaN

    • 如果是NaN,返回true,否则,返回false

    强制数据类型转化:number、Boolean、string、parseint、parsefloat

    隐式数据类型转化: if() 2+"5";运算符、while

    除了强制类型转换(能看到的),其他都是隐式数据转换 

    引用函数的类型是function

let和const

let:块级作用域

ES6中新增的声明变量的关键字,用法同var

  • 不同点

    • let不存在变量提升

    • let不能重复声明同一个变量,可以重复赋值

    • let可以识别块级作用域,成为局部变量,只在当前的块级作用域起作用

conat

ES6新增的关键字,用来声明常量(不变的量)

  • 只能在声明的同时赋值

  • 一般常量的名字全部大写

  • 常量不能重复赋值

  • 可以识别块级作用域

  • 只在当前的块级作用域起作用

  • 不存在变量提升

对象

new

使用new操作符调用构造函数时,会经历4个阶段

1.创建一个对象2.将这个对象的proto成员指向了构造函数对象的prototype成员对象,这是最关键的一步3.将构造函数的作用域赋给新对象,this就是新对象 4.返回新对象

var zhangsan = {};
zhangsan.__proto__=person.prototype;
person.call(zhangsan);
return zhangsan;

对象的创建:

  1. 通过构造函数创建类-------工厂函数

    function Computer(yanse,jiage){
    this.color = yanse;
    this.price = jiage;
    this.study = function(){
    console.log("跶游戏")
    }
    }//通过new一个类,实例化一个对象
    let dell =new Computer("red","9999");
    console.log(dell)
    //dell.color = "yellow";
    //dell.price = "10000";
  2. 通过class关键字创建类

    class Person{
    //构造函数
    constructor(arms,eye){
    this.arms = arms;
    this.eye = eye;
    this.study = function(){
    console.log("街道口");
    }
    }
    }
    let zhangsan = new Person(2,2);
    console.log(zhangsan);
  3. json(javascript object notation)直接创建对象 轻量级的数据交换格式

    {
    name:"李四",
    age:15,
    key:value
    }
    let mi = {
    name :"小米手机",
    color:"red",
    price:318,
    watch:function(){
    console.log("看电视");
    return 0;
    },
    cpu:"123"
    }
    console.log(mi.cpu)
    console.log(mi)

    proto 每个对象都有的属性,用来继承,指向它的构造函数的原型

对象的遍历

查看某个对象的构造函数,通过.constructor

console.log(mi.constructor)

判断某个对象是不是属于某个构造函数 instanceof如果是,返回true;否则,返回false

console.log(zhangsan instanceof Person)

每一个函数都有一个属性.prototype

console.log(zhangsan.constructor.prototype)

每个对象的proto指向构造函数的prototype

console.log(zhangsan.__proto__=zhangsan.constructor.prototype)//true

字符串对象

属性​ length //对象方法

  • 查询:

    • charAt //获取字符串某个位置的值(0~n)

    • charCodeAt()//获取字符串的ASCII

    • search //只能配合正则使用

    • match //某个字符在字符串的位置情况,返回值是一个数组,它可以配合正则使用

    • indexOf(string) //获取某个字符在字符串首次出现的位置,如果没有找到返回值为-1

    • lastIindexOf(string) //获取某个字符在字符串最后出现的位置,如果没有找到返回值为-1

    • replace("string","string") //替换字符串中的某个字符,第一个参数为要替换的参数,第二参数为替换后的参数,可以配合正则使用

  • 截取:

    • slice(int,int) //截取字符串中的一段,两个参数都是代表位置,从第一个参数的的位置截取到第二个参数的位置,包含第一个不包含第二个,如果只有开始的位置将一直截取结束;如果是负数,将倒数

    • substr //截取字符串中的一段,第一个参数为开始截取的位置,第二个参数为截取长度

    • substring(int,int) //和slice类似,但它不接收负数

  • 其他:

    • toLowerCase //把里面的大写字母转化为小写字母

    • toUpperCase //把里面的小写字母转化为大写字母

    • split(string) //把字符串以某种分割符分割为数组,可以配合正则使用

    • trim //去掉字符串中的前后空格

    • concat //拼接

数组对象

​ concat()---数组的拼接,返回新数组,原数组不会改变,参数:可以传一个或者多个元素,也可以是其他数组字符串对象

  • 增删

    • unshift// 给数组的最前面添加一个或多个元素,返回新数组,原数组发生变化.参数:要添加的元素

    • shift----删除数组中的第一个元素,返回删除的元素,原数组发生变化,参数:无

    • push-----给数组添加一个或多个元素,返回新数组的长度,原数组发生变化,参数:要添加的元素

    • pop------删除数组中的最后一个元素,返回被删除的元素。原数组发生变化,是删除之后的数组,参数:无

    • slice-----截取数组的一部分,返回被截取的部分,原数组不变,参数:参数1.截取的开始位置,参数2.截取结束的位置,不包括