javascript清晰的快速入门

javascript介绍

JavaScript是一种高级的、解释型的脚本语言,常用于为网页添加交互性和动态性。它是一种基于对象和事件驱动的语言,最初由网景公司(Netscape)在1995年开发并命名为JavaScript。
JavaScript通常用于前端开发,用于操作HTML元素、处理用户输入、响应事件等。它可以通过在HTML文件中嵌入`<script>`标签来引入和执行。也可以将JavaScript代码放在外部文件中,并通过`<script src="filename.js"></script>`标签引用。
JavaScript具有以下特点:
1. **简单易学:** JavaScript语法类似于C语言,易于学习和理解。它使用动态类型,无需声明变量类型,具有灵活性。
2. **与HTML和CSS集成:** JavaScript可以直接操作HTML元素和CSS样式,动态地改变网页的内容和外观。
3. **跨平台:** JavaScript可以在几乎所有的现代浏览器上运行,包括桌面和移动设备。
4. **面向对象:** JavaScript是一种基于对象的语言,支持面向对象编程的特性,如封装、继承和多态。
5. **事件驱动:** JavaScript可以通过事件监听和处理来响应用户的操作,例如点击按钮、输入文本等。
6. **强大的库和框架支持:** JavaScript有许多流行的库和框架,如jQuery、React、Vue.js等,可以加快开发速度和提供更丰富的功能。
除了在网页中使用,JavaScript也可以在服务器端运行,称为Node.js。Node.js使用V8引擎解释和执行JavaScript代码,使得JavaScript可以用于开发服务器端应用程序。
总之,JavaScript是一种广泛应用于网页开发和服务器端开发的脚本语言,具有丰富的特性和强大的生态系统,是现代Web开发中必不可少的一部分。

1.js组成部分

JavaScript可以分为以下几个主要的组成部分:


1. **核心语言(Core Language):** 核心语言是JavaScript的基础,包括变量、数据类型、运算符、控制结构(如条件语句和循环)、函数等。这些语言特性构成了JavaScript的基本语法和逻辑。


2. **DOM(Document Object Model):** DOM是JavaScript的文档对象模型,它提供了对HTML文档的结构化访问和操作。使用DOM,JavaScript可以通过获取和修改文档中的元素、属性和样式,实现对网页的动态更新和交互。


3. **BOM(Browser Object Model):** BOM是JavaScript的浏览器对象模型,它提供了对浏览器窗口和浏览器功能的访问和控制。BOM包括Window对象、Navigator对象、Location对象等,通过BOM,JavaScript可以控制浏览器的行为,例如打开新窗口、获取浏览器信息等。


4. **API(Application Programming Interface):** API是一组提供给开发者使用的接口,用于访问和操作特定功能或服务。JavaScript可以使用各种API,例如浏览器提供的Web API(如Geolocation API、Fetch API)、第三方库和框架的API(如jQuery、React)等。API可以扩展JavaScript的功能,使其能够处理更多的任务和场景。


以上是JavaScript的主要组成部分,它们相互配合,使得JavaScript能够实现丰富的功能和交互效果。核心语言提供了基础的语法和逻辑,DOM和BOM提供了访问和操作网页和浏览器的能力,而API则提供了各种功能和服务的接口。这些组成部分共同构成了JavaScript的生态系统,使其成为一种强大的脚本语言。

2.js之hello

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- js标签 在里面写js相关的内容 -->
    <script>
        // 这是js弹窗   hello  word 是一个需要被弹出的文本内容
     alert("hello word")

document.write("将内容打印到网页上")
    </script>
</body>
</html>

3.js书写的位置

js和css一样有很多书写方式写在页面上让其展现效果

1.行内式js代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <!-- 写在a标签的href属性上 -->
    <a href="javascript:alert('我是弹窗')"></a>
    <!-- 写在div标签上,是一个点击事件 -->
    <div  onclick="alert('我是弹窗')">点击</div>
<!-- 
    注:onclick是一个点击事件,点击元素时会执行jS代码
 -->
</body>
</html>

2.内嵌式js代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
  <!-- 在html页面写一个script标签,在标签内部写js代码 -->
  <script type="text/javascript">

  document.write("打印出内容")
  
  alert("这是内容")

  </script>
</body>
</html>

3.外链式js代码

第一步,创建扩展名是js的文件,例如:zjq.js  ,zhao.js, qdf.js

 第二步引用外部的js文件

:引用js的script标签可以在body标签里面 ,也可以在head标签里面,看当时的需求而定!!!!

 4.js注释和规范

注释用来在源码中增加提示、笔记、建议、警告等信息,可以帮助阅读和理解源码。在调试时,可以用来将一段代码屏蔽掉,防止其运行。

JavaScript的注释分为单行注释 // 和多行注释 /* */ 两种。

1.在单行注释中,在 // 后的文本都会视为注释,用法如下。

function comment() {
  // 这是单行注释
  console.log("Hello world!"); // 这是单行注释
}
comment();


2.在多行注释中,使用 /* 和 */ 包裹的文本就会视为注释,用法如下:

function comment() {
  /* 单行注释 */
  /* 多行注释,
     直到终止符号才结束 */
  console.log("Hello" + /* 引入x的值 */ + " world!");
}
comment();


二、JavaScript注释使用建议
注释的规范使用是可以方便他人阅读你的代码,同时,当你以后再次看的时候,也能很快回忆起。**写注释的时候,请记得写正确的注释,错误或有歧义的注释不如不写注释。**以下是本人对注释使用的一些心得,各位读者有别的想法可以提出,大家共同讨论。
 

 5.变量

console.log(23423425235)

1,变量指的是在程序中保存数据的一个容器
2,变量是计算机内存中存储数据的一个标识,根据变量名可以获取到内存中的存储数据
3,意思就是说在内存中存储一个数据,然后给和这个数据起一个名字,为了方面后期对数据进行相关的操作
4,语法:  var  变量名 = 值



//  定义一个变量
var  num;

//给一个变量赋值,因为已经定义过了,只需要赋值
num=12

//定义一个变量同时给其赋值
var num2=234234;

6.变量规范和规则

规则:必须遵守,不遵守就是错的

    1.一个变量名称可以由字母,数字,下划线组成,以及美元符号$

    2.严格区分大小写

    3.不能由数组开头

    4.不能是保留字或者关键字

规范:  建议遵守的是(开发者默认的),不遵守不会报错

    1.变量名尽量是语义化,知名见意

    2.遵守驼峰命名法,由多个单词组成,首字母大写

    3.不要使用中文

7.数据类型

1、Undefined

Undefined类型只有一个值,即特殊值undefined。在使用var声明变量,但未对其加以初始化时,这个变量值就是undefined。

2、Null

Null类型是第二个只有一个值的数据类型。其特殊值就是Null。从逻辑角度上看,null是一个空的对象指针。而这也正是使用typeof操作符检测null值,会返回“object”的原因。

3、Boolean

即布尔类型,该类型有两个值:true、false。需要注意的是,Boolean类型的字面值true和false是区分大小写的。也就是说,True和False(以及其它的混合大小形式)都不是Boolean值,只是标识符。

4、Number

该类型的表示方法有两种形式,名列前茅种是整数,第二种为浮点数。整数:可以通过十进制,八进制,十六进制的字面值来表示。浮点数:就是该数值中必须包含一个小数点,且小数点后必须有一位数字。

//整数
const num=234234;
//浮点数
const number=234234.234

5、String

String类型用于表示由零或多个16位的Unicode字符组成的字符序列,即字符串。至于用单引号,还是双引号,在js中还是没有差别的。记得成对出现。

const str="字符串"

const str='字符串'

//一样的效果

6、Symbol类型

符号 (Symbols) 是 ECMAScript 第 6 版新定义的。符号类型是少数的并且是不可修改的。Symbol 函数前不能使用 new 命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述

7、Object

Object数据类型,称为对象,是一组数据和功能(函数)的集合。可以用new操作符后跟要创建的对象类型的名称来创建。也可以用字面量表示法创建。在其中添加不同名(包含空字符串在内的任意字符串)的属性。

const  obj={'name':赵建强,age:234}
//这样的就是obj对象类型的数据

8、Array

JavaScript 数组用方括号书写,数组的项目由逗号分隔。

创建数组的方法:
1.空数组
var arr=new Array()
2. 利用数组
var arr=[]
3.添加内容的数组
var arr=[1,"你",true]

9、Function

ECMAScript中的函数是对象,与其他引用类型一样具有属性和方法。因此,函数名实际是一个指向函数对象的指针。

function  方法名字(形参){  //形参看需求


  //代码体

}

8.检测数据类型

1. typeof

可以判断数据类型,它返回表示数据类型的字符串(返回结果只能包括number,boolean,string,function,object,undefined);
可以使用typeof判断变量是否存在(如if(typeof a!="undefined"){...});
Typeof 运算符的问题是无论引用的对象是什么类型 它都返回object

typeof {}   // object
typeof  [1,2]   // object
typeof /\s/    //object

 .2.instanceof

原理 因为A instanceof B 可以判断A是不是B的实例,返回一个布尔值,由构造类型判断出数据类型

console.log(arr instanceof Array ); // true
console.log(date instanceof Date ); // true
console.log(fn instanceof Function ); // true
//注意: instanceof 后面一定要是对象类型,大小写不能写错,该方法试用一些条件选择或分支

9.数据类型转换

一:转数值

  1.Numble();

  语法:Numble(要转换的内容)

  结果:转换好数值类型的结果

  如果转换的不是数值则输出NaN

  

  2.parseInt();

  语法:parseInt(要转换的内容)

  结果:转换好数值类型的结果

  一个一个解析,检测到不是数字之后就不输出后面的内容

  3.parseFloat();

  语法:parseFloat(要转换的内容)

  结果:转换好数值类型的结果

  可以解析小数点

二:转字符串

  1.String()

  语法:String(要转换的内容)

  结果:转换好字符串类型的结果

  2.toString()

  语法:要转换的内容.toString()

  结果:转换好字符串的结果

  

  3.隐形转换

  +号一边是字符串,另一边就会隐形转换成字符串

  例:

    var num = 20;

    var res = num + '11'

    console.log(res)

    输出结果为:2011

三:转布尔

  Boolean();

  语法:Boolean(要转换的内容)

  结果:转换好的数值类型

  温馨提示:

      这五个值转换成布尔为false的内容:数字:0;NaN;空字符串:' ';undefined;null

10.js运算符

JavaScript中包含多种运算符,用于执行各种数学和逻辑操作。以下是JavaScript中常用的运算符:

1. **算术运算符(Arithmetic Operators):** 用于执行基本的算术计算,例如加法、减法、乘法和除法。
   - 加法:+
   - 减法:-
   - 乘法:*
   - 除法:/
   - 取模(取余数):% 
   - 自增:++
   - 自减:--

2. **赋值运算符(Assignment Operators):** 用于将值赋给变量。
   - 简单赋值:=
   - 加法赋值:+=
   - 减法赋值:-=
   - 乘法赋值:*=
   - 除法赋值:/=
   - 取模赋值:%=
   - 左移赋值:<<=
   - 右移赋值:>>=
   - 无符号右移赋值:>>>=
   - 按位与赋值:&=
   - 按位或赋值:|=
   - 按位异或赋值:^=

3. **比较运算符(Comparison Operators):** 用于比较两个值并返回布尔值(true或false)。
   - 相等:==
   - 不相等:!=
   - 全等(值和类型都相等):===
   - 不全等(值或类型有一个不相等):!==
   - 大于:>
   - 小于:<
   - 大于等于:>=
   - 小于等于:<=

4. **逻辑运算符(Logical Operators):** 用于组合和操作布尔值。
   - 逻辑与:&&
   - 逻辑或:||
   - 逻辑非:!

5. **位运算符(Bitwise Operators):** 用于对二进制数进行位操作。
   - 按位与:&
   - 按位或:|
   - 按位异或:^
   - 按位非:~
   - 左移:<<
   - 右移:>>
   - 无符号右移:>>>

6. **条件运算符(Conditional Operator):** 也被称为三元运算符,用于根据条件选择不同的值。
   - 条件 ? 结果1 : 结果2

7. **typeof运算符:** 用于确定给定变量或表达式的数据类型。
   - typeof 变量

8. **delete运算符:** 用于删除对象的属性或数组中的元素。
   - delete 对象.属性
   - delete 数组[索引]



以上是JavaScript中常用的运算符。通过运算符,可以进行数学计算、赋值、比较、逻辑操作等,帮助开发者实现各种复杂的功能和逻辑。

11.三目运算符

语法: 表达式1?表达式2:表达式3

表达式1是一个条件   值为boolean类型

表达式1是 true 就执行表达式2

表达式1是 false就执行表达3

const  a=10>3?a=23:a=456;
//如果a大于3成立就给a重新赋值为23,反之就是456

12.流程控制语句

谓的流程控制就是控制代码的执行顺序。

流程语句分类:

  • 顺序结构: 按照定义的顺序,从上到下依次执行。
  • 分支结构: 根据不同的情况,执行分支代码
  • 循环结构: 重复做某一件事情

分支结构

1.if语句
if(条件表达式){
   //执行语句
}
if()里面的条件表达式满足的话执行{}里面的语句

案例  一   弹出一个输入框  要求输入用户的年龄   如果年龄大于等于18岁的年龄,输入可以进入网吧

2.if-else
if(条件表达式){
  //执行语句
}else{
 // 执行语句
}

表达式满足真 执行if语句 ,反之执行 else语句

案例二   判断闰年还是平年
接受弹出的输入框的数据,进行判断 。要么弹出闰年 要么弹出平年
3,if-else if-else

var  a=90
if(a>90){
   //执行语句
}else if(a>60){
   //执行语句
   
}else{
   //执行最后的语句
}
案例三 浏览器页面弹出输入框请输入成绩,根据输入的成绩进行判断成绩的等级(自我解决)

4.switch 语句
语法:

  switch (key) {
    case value:
        
        break;
     case value:

          break;
  
    default:
        break;
  }
switch注意:
   1. key: 通常是变量
   2. value值的类型与key一样才行
   3.如果case里面没有break就执行下一个


案例:

var key=15
  switch (key) {
    case 10:
        alert(2)
        break;
     case 15:
        alert(1) 
        break;
  
    default:
        alert(100)
        break;
  }      
  满足一个条件就会执行相对应的数据

5.if else if 与switch区别

区别 :

确定值的时候用switch

确定范围用if

效率上switch高 ,只要满足条件就会直接跳到它所需要执行的代码上

循环结构

循环目的:重复执行某些代码

循环语句有:
     for循环
     while循环
     do..while 循环

1 ,for循环

for 重置执行某些的代码,通常跟计数有关系

语法结构:
  for(初始化变量;条件表达式;操作表达式){
     //循环体
  }
  1.初始化变量是用var 声明一个普通的变量,通常用于计算器使用
  2.条件表达式就是用于判断条件是否需要再次被执行,也就是判断 终止的条件
  3.操作表达式 每次循环最后执行的代码,经常是变量的更行
  for(var i=0;i<20;i++){
    console.log(i)
}
输出结果1到20


案例一 用弹出输入框 输入班级的人数  ,然后输出班级每个人成绩最后相加,弹出总成绩

<script>

var  name=prompt("请输入班级人数:")
var sum=0
   for(var i=1;i<=name;i++){
          var age=prompt("请输入成绩:")
           sum+=Number(age)

   }
   alert("总成绩是:"+sum)
</script>



倒三角案例:


for(var i=0;i<5;i++){
    for(var j=i;j<5;j++){
        document.write("*")
    }
    document.write("<br/>")
}



9*9乘法表

for(var i=1;i<=9;i++){
    for(var j=1;j<=i;j++){
        document.write(j+"*"+i+'='+i*j,'\t')
    }
    document.write("<br/>")
}

2.while循环

while(true){
//只要括号里面表达式是true就一直执行下去
   consoe.log("执行下去")
}



const cc=0
while(cc>12){
//只要括号里面表达式大于12就会停止运行
   consoe.log("执行下去")
   cc++
}

13.js函数代码

JavaScript中函数是一种可重复使用的代码块,用于执行特定的任务或计算。以下是JavaScript函数的一些重要知识点:
1. **函数定义和调用:** 函数可以通过`function`关键字来定义,然后可以通过函数名加括号来调用函数。例如:


   function myFunction() {
     // 函数体
   }
   myFunction(); // 调用函数
   


2. **函数参数:** 函数可以接受参数,用于传递数据给函数。参数可以在函数定义时指定,调用函数时传入具体的值。例如:


   function greet(name) {
     console.log("Hello, " + name + "!");
   }
   greet("Alice"); // 输出: Hello, Alice!
   


3. **函数返回值:** 函数可以使用`return`语句返回一个值。返回值可以在函数调用时被接收并使用。例如:


   function add(a, b) {
     return a + b;
   }
   var result = add(2, 3); // result的值为5
   


4. **函数作用域:** JavaScript中的函数具有自己的作用域,在函数内部声明的变量只在函数内部可见。这意味着函数外部无法访问函数内部的变量。例如:


   function myFunction() {
     var x = 10; // 函数内部的变量
     console.log(x);
   }
   console.log(x); // 报错:x未定义
   


5. **匿名函数和立即执行函数:** JavaScript中可以使用匿名函数(没有函数名)来定义函数。匿名函数可以直接执行,这种称为立即执行函数(Immediately Invoked Function Expression,IIFE)。例如:


   (function() {
     console.log("立即执行的匿名函数");
   })();
  


6. **函数表达式:** 函数表达式是将函数赋值给变量或对象属性的方式。函数表达式可以作为变量传递、作为回调函数使用,或者作为对象方法。例如:


   var greet = function(name) {
     console.log("Hello, " + name + "!");
   };
   greet("Bob"); // 输出: Hello, Bob!
   


7. **递归函数:** 递归函数是指在函数体内调用自身的函数。递归函数常用于解决需要重复执行相同操作的问题。例如:


   function factorial(n) {
     if (n === 0) {
       return 1;
     } else {
       return n * factorial(n - 1);
     }
   }
   console.log(factorial(5)); // 输出: 120
   


8. **高阶函数:** 高阶函数是指可以接受函数作为参数或返回函数的函数。高阶函数可以用于函数的组合和封装。例如:


   function multiplyBy(factor) {
     return function(number) {
       return number * factor;
     };
   }
   var double = multiplyBy(2);
   console.log(double(5)); // 输出: 10
   


以上是JavaScript函数的一些重要知识点。函数是JavaScript中的核心概念之一,掌握这些知识点可以帮助你更好地理解和使用JavaScript中的函数。

14.Obj对象的所有方法

JavaScript中的对象是一种复合数据类型,它可以存储键值对。对象的方法是定义在对象上的函数,用于执行特定的操作。以下是JavaScript对象数据类型的一些常用方法及其操作:
1. **Object.keys():** 返回一个包含对象所有可枚举属性的数组。


   const obj = { a: 1, b: 2, c: 3 };
   const keys = Object.keys(obj);
   console.log(keys); // 输出: ["a", "b", "c"]
   


2. **Object.values():** 返回一个包含对象所有可枚举属性的值的数组。


   const obj = { a: 1, b: 2, c: 3 };
   const values = Object.values(obj);
   console.log(values); // 输出: [1, 2, 3]
   


3. **Object.entries():** 返回一个包含对象所有可枚举属性的键值对的数组。

   
   const obj = { a: 1, b: 2, c: 3 };
   const entries = Object.entries(obj);
   console.log(entries); // 输出: [["a", 1], ["b", 2], ["c", 3]]
   


4. **Object.assign():** 将一个或多个源对象的属性复制到目标对象,并返回目标对象。


   const target = { a: 1 };
   const source = { b: 2, c: 3 };
   const result = Object.assign(target, source);
   console.log(result); // 输出: { a: 1, b: 2, c: 3 }
   


5. **Object.hasOwnProperty():** 判断对象是否具有指定的属性。


   const obj = { a: 1, b: 2 };
   console.log(obj.hasOwnProperty("a")); // 输出: true
   console.log(obj.hasOwnProperty("c")); // 输出: false
   


6. **Object.freeze():** 冻结对象,使其不可修改。


   const obj = { a: 1, b: 2 };
   Object.freeze(obj);
   obj.a = 3; // 无效操作,对象不可修改
   console.log(obj); // 输出: { a: 1, b: 2 }
   


7. **Object.seal():** 封闭对象,使其属性不可添加或删除,但属性值可修改。


   const obj = { a: 1, b: 2 };
   Object.seal(obj);
   obj.c = 3; // 无效操作,无法添加新属性
   delete obj.a; // 无效操作,无法删除属性
   obj.b = 4; // 有效操作,修改属性值
   console.log(obj); // 输出: { a: 1, b: 4 }
   


8. **Object.create():** 创建一个新对象,使用现有对象作为原型。

  
   const obj = { a: 1 };
   const newObj = Object.create(obj);
   console.log(newObj); // 输出: {}
   console.log(newObj.a); // 输出: 1,继承自原型对象
   


9. **Object.getPrototypeOf():** 返回指定对象的原型对象。
 

 
   const obj = {};
   const proto = Object.getPrototypeOf(obj);
   console.log(proto); // 输出: {}
   


10. **Object.defineProperty():** 定义对象的新属性或修改现有属性的特性。


    const obj = {};
    Object.defineProperty(obj, "name", {
      value: "Alice",
      writable: false, // 不可写
      enumerable: true, // 可枚举
      configurable: true, // 可配置
    });
    console.log(obj.name); // 输出: Alice
    obj.name = "Bob"; // 无效操作,属性不可写
    console.log(obj.name); // 输出: Alice
    


以上是JavaScript对象数据类型的一些常用方法及其操作。这些方法可以用于操作和处理JavaScript中的对象,帮助开发者更方便地管理和操作对象的属性和特性。

15.数组相关方法

JavaScript中的数组是一种特殊的对象,用于存储多个值。数组有许多内置的方法,用于执行各种操作。以下是JavaScript数组的常用方法:
1. **push():** 将一个或多个元素添加到数组的末尾,并返回新数组的长度。

  
   const arr = [1, 2, 3];
   const length = arr.push(4, 5);
   console.log(arr); // 输出: [1, 2, 3, 4, 5]
   console.log(length); // 输出: 5
   


2. **pop():** 移除数组的最后一个元素,并返回该元素的值。

 
   const arr = [1, 2, 3];
   const lastElement = arr.pop();
   console.log(arr); // 输出: [1, 2]
   console.log(lastElement); // 输出: 3
   


3. **shift():** 移除数组的第一个元素,并返回该元素的值。

   
   const arr = [1, 2, 3];
   const firstElement = arr.shift();
   console.log(arr); // 输出: [2, 3]
   console.log(firstElement); // 输出: 1
   


4. **unshift():** 将一个或多个元素添加到数组的开头,并返回新数组的长度。


   const arr = [1, 2, 3];
   const length = arr.unshift(0, -1);
   console.log(arr); // 输出: [-1, 0, 1, 2, 3]
   console.log(length); // 输出: 5
   


5. **concat():** 将一个或多个数组合并为一个新数组。


   const arr1 = [1, 2];
   const arr2 = [3, 4];
   const newArr = arr1.concat(arr2);
   console.log(newArr); // 输出: [1, 2, 3, 4]
   


6. **slice():** 返回一个从原数组中选定元素的浅拷贝数组。

   
   const arr = [1, 2, 3, 4, 5];
   const newArr = arr.slice(2, 4);
   console.log(newArr); // 输出: [3, 4]
   


7. **splice():** 从数组中添加/删除元素,或替换元素。


   const arr = [1, 2, 3, 4, 5];
   arr.splice(2, 2, "a", "b");
   console.log(arr); // 输出: [1, 2, "a", "b", 5]


8. **join():** 将数组的所有元素连接成一个字符串。


   const arr = ["Hello", "World"];
   const str = arr.join(" ");
   console.log(str); // 输出: "Hello World"
   


9. **indexOf():** 返回数组中第一个找到的指定元素的索引,如果没有找到则返回-1。


   const arr = [1, 2, 3, 4, 5];
   const index = arr.indexOf(3);
   console.log(index); // 输出: 2
   


10. **includes():** 判断数组是否包含指定元素,返回一个布尔值。

 
    const arr = [1, 2, 3, 4, 5];
    const isIncluded = arr.includes(3);
    console.log(isIncluded); // 输出: true
    


11. **forEach():** 遍历数组的每个元素,并对每个元素执行提供的函数。


    const arr = [1, 2, 3];
    arr.forEach(function(element) {
      console.log(element);
    });
    // 输出:
    // 1
    // 2
    // 3
    


12. **map():** 创建一个新数组,其中的每个元素是调用提供的函数后的返回值。


    const arr = [1, 2, 3];
    const newArr = arr.map(function(element) {
      return element * 2;
    });
    console 

除了上述提到的常用方法之外,JavaScript数组还有一些其他常用的方法,如下所示:

13. **filter():** 创建一个新数组,其中包含通过指定函数测试的所有元素。

    const arr = [1, 2, 3, 4, 5];
    const newArr = arr.filter(function(element) {
      return element % 2 === 0;
    });
    console.log(newArr); // 输出: [2, 4]

14. **reduce():** 对数组的每个元素执行一个提供的函数,并返回一个累积的结果。
 
    const arr = [1, 2, 3, 4, 5];
    const sum = arr.reduce(function(accumulator, currentValue) {
      return accumulator + currentValue;
    });
    console.log(sum); // 输出: 15
    

15. **reduceRight():** 从数组的最后一个元素开始,对数组的每个元素执行一个提供的函数,并返回一个累积的结果。

    const arr = [1, 2, 3, 4, 5];
    const sum = arr.reduceRight(function(accumulator, currentValue) {
      return accumulator + currentValue;
    });
    console.log(sum); // 输出: 15
    

16. **find():** 返回数组中通过指定函数测试的第一个元素的值。

    const arr = [1, 2, 3, 4, 5];
    const result = arr.find(function(element) {
      return element > 3;
    });
    console.log(result); // 输出: 4
    

17. **findIndex():** 返回数组中通过指定函数测试的第一个元素的索引。

    const arr = [1, 2, 3, 4, 5];
    const index = arr.findIndex(function(element) {
      return element > 3;
    });
    console.log(index); // 输出: 3
    

18. **every():** 检测数组中的所有元素是否都通过指定函数的测试。
  
    const arr = [1, 2, 3, 4, 5];
    const result = arr.every(function(element) {
      return element > 0;
    });
    console.log(result); // 输出: true
    

19. **some():** 检测数组中是否至少有一个元素通过指定函数的测试。
 
    const arr = [1, 2, 3, 4, 5];
    const result = arr.some(function(element) {
      return element > 3;
    });
    console.log(result); // 输出: true
   

20. **sort():** 对数组的元素进行排序。

    const arr = [3, 1, 2, 5, 4];
    arr.sort();
    console.log(arr); // 输出: [1, 2, 3, 4, 5]
    

//a-b 是从小到大  b-a从大到小
arr.sort((a,b)=>a-b)

21. **reverse():** 颠倒数组中元素的顺序。
  
    const arr = [1, 2, 3, 4, 5];
    arr.reverse();
    console.log(arr); // 输出: [5, 4, 3, 2, 1]
    

22. **toString():** 将数组转换为字符串,并返回结果。
    
    const arr = [1, 2, 3, 4, 5];
    const str = arr.toString();
    console.log(str); // 输出: "1,2,3,4,5"
    

23. **toLocaleString():** 将数组转换为本地化字符串,并返回结果。

    const arr = [1, 2, 3, 4, 5];
    const str = arr.toLocaleString();
    console.log(str); // 输出: "1,2,3,4,5"
    


这些是JavaScript数组的一些常见方法,用于对数组进行各种操作和处理。它们可以帮助开发者更方便地操作和处理数组中的元素。 

16.字符串相关的方法

JavaScript中的字符串(String)是一种表示文本数据的数据类型。字符串是不可变的,即一旦创建,就不能被修改。JavaScript提供了许多字符串相关的方法,用于操作和处理字符串。下面是一些常用的字符串方法:
1. **length:** 返回字符串的长度。


   const str = "Hello";
   console.log(str.length); // 输出: 5
   


2. **charAt():** 返回指定索引位置处的字符。

  
   const str = "Hello";
   console.log(str.charAt(1)); // 输出: "e"
   


3. **concat():** 连接两个或多个字符串,并返回新的字符串。


   const str1 = "Hello";
   const str2 = " World";
   const result = str1.concat(str2);
   console.log(result); // 输出: "Hello World"
   


4. **indexOf():** 返回指定字符或子字符串第一次出现的索引,如果没有找到则返回-1。

  
   const str = "Hello World";
   console.log(str.indexOf("o")); // 输出: 4
   


5. **lastIndexOf():** 返回指定字符或子字符串最后一次出现的索引,如果没有找到则返回-1。


   const str = "Hello World";
   console.log(str.lastIndexOf("o")); // 输出: 7
   


6. **slice():** 提取字符串的一部分,并返回一个新字符串。


   const str = "Hello World";
   console.log(str.slice(6, 11)); // 输出: "World"
   


7. **substring():** 提取字符串的一部分,并返回一个新字符串。与slice()类似,但substring()不接受负索引。


   const str = "Hello World";
   console.log(str.substring(6, 11)); // 输出: "World"
   


8. **substr():** 提取字符串的一部分,并返回一个新字符串。第一个参数指定开始提取的位置,第二个参数指定提取的长度。


   const str = "Hello World";
   console.log(str.substr(6, 5)); // 输出: "World"
   


9. **toUpperCase():** 将字符串转换为大写。


   const str = "Hello";
   console.log(str.toUpperCase()); // 输出: "HELLO"
   


10. **toLowerCase():** 将字符串转换为小写。

 
    const str = "Hello";
    console.log(str.toLowerCase()); // 输出: "hello"
    


11. **trim():** 去除字符串两端的空格,并返回一个新字符串。


    const str = "  Hello World  ";
    console.log(str.trim()); // 输出: "Hello World"
    


12. **replace():** 替换字符串中的字符或子字符串,并返回一个新字符串。


    const str = "Hello World";
    const newStr = str.replace("World", "JavaScript");
    console.log(newStr); // 输出: "Hello JavaScript"
    


13. **split():** 将字符串分割为字符串数组,并返回该数组。


    const str = "Hello,World";
    const arr = str.split(",");
    console.log(arr); // 输出: ["Hello", "World"]
    


这些方法可以用于操作和处理JavaScript字符串。它们能够帮助开发者在处理字符串时进行各种操作,如获取字符串长度、提取子字符串、替换字符等。

16.json格式字符串

前端中经常需要处理JSON格式的字符串。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写。以下是一些在前端中处理JSON格式字符串的常见操作:

1. **JSON.parse():** 将JSON字符串解析为JavaScript对象。
  
   const jsonString = '{"name": "John", "age": 30, "city": "New York"}';
   const jsonObj = JSON.parse(jsonString);
   console.log(jsonObj); // 输出: { name: 'John', age: 30, city: 'New York' }
 

2. **JSON.stringify():** 将JavaScript对象转换为JSON字符串。
 

   const obj = { name: 'John', age: 30, city: 'New York' };
   const jsonString = JSON.stringify(obj);
   console.log(jsonString); // 输出: '{"name":"John","age":30,"city":"New York"}'
 


3. **处理嵌套的JSON:**
   如果JSON字符串中包含嵌套的对象或数组,你可以通过嵌套调用`JSON.parse()`和`JSON.stringify()`来处理。
  

   const nestedJsonString = '{"name": "John", "info": {"age": 30, "city": "New York"}}';
   const nestedJsonObj = JSON.parse(nestedJsonString);
   console.log(nestedJsonObj); // 输出: { name: 'John', info: { age: 30, city: 'New York' } }
   // 修改嵌套对象的值
   nestedJsonObj.info.age = 31;
   // 转换回JSON字符串
   const updatedJsonString = JSON.stringify(nestedJsonObj);
   console.log(updatedJsonString);


4. **处理JSON中的日期:**
   JSON规范并不直接支持日期对象。在处理包含日期的JSON时,你可以使用自定义的转换函数。
   const jsonStringWithDate = '{"name": "John", "birthDate": "2023-01-01T12:00:00Z"}';
   const jsonObjWithDate = JSON.parse(jsonStringWithDate, (key, value) => {
     if (key === 'birthDate') {
       return new Date(value);
     }
     return value;
   });
   console.log(jsonObjWithDate.birthDate); // 输出: 2023-01-01T12:00:00.000Z
  


这些方法可以帮助你在前端中有效地处理JSON格式的字符串,实现数据的解析和序列化。

17.模板字符串

在JavaScript中,模板字符串是一种特殊的字符串,用于更方便地创建包含变量或表达式的字符串。模板字符串使用反引号 \`(在键盘上与 tilde ~ 共享同一个键位) 包裹字符串内容,并使用 `${}` 语法嵌入变量或表达式。以下是一些使用模板字符串的示例:
1. **基本用法:**


   const name = 'John';
   const greeting = `Hello, ${name}!`;
   console.log(greeting); // 输出: Hello, John!
   


2. **多行字符串:**
   使用模板字符串可以轻松创建多行字符串,而无需使用换行符。


   const multiLineString = `
     This is a
     multi-line
     string.
   `;
   console.log(multiLineString);
   /*
   输出:
     This is a
     multi-line
     string.
   */
   


3. **表达式嵌入:**
   模板字符串中可以嵌入任意的表达式。

 
   const a = 5;
   const b = 10;
   const result = `The sum of ${a} and ${b} is ${a + b}.`;
   console.log(result); // 输出: The sum of 5 and 10 is 15.
   


4. **函数调用:**
   你可以在模板字符串中调用函数并使用函数的返回值。

 
   function capitalize(str) {
     return str.charAt(0).toUpperCase() + str.slice(1);
   }
   const city = 'new york';
   const formattedCity = `I live in ${capitalize(city)}.`;
   console.log(formattedCity); // 输出: I live in New york.
   


5. **嵌套模板字符串:**
   模板字符串可以嵌套在彼此内部。

  
   const firstName = 'John';
   const lastName = 'Doe';
   const fullName = `My name is ${firstName} ${lastName}.`;
   const greetingWithFullName = `Greetings! ${fullName}`;
   console.log(greetingWithFullName); // 输出: Greetings! My name is John Doe.
   


模板字符串使得处理字符串变得更加直观和便捷,特别是在需要包含变量或表达式的场景下。

18.数字常用方法

在前端开发中,经常需要对数字进行处理和操作。以下是一些常用的数字方法和函数:
1. **toFixed():** 将数字转换为指定小数位数的字符串表示。

   
   const num = 10.3456;
   const fixedNum = num.toFixed(2);
   console.log(fixedNum); // 输出: "10.35"
   


2. **parseFloat() 和 parseInt():** 分别用于将字符串转换为浮点数或整数。

   
   const floatNum = parseFloat("10.25"); // 将字符串转换为浮点数
   const intNum = parseInt("15"); // 将字符串转换为整数
   console.log(floatNum); // 输出: 10.25
   console.log(intNum); // 输出: 15
   


3. **Number():** 将字符串、布尔值或其他数据类型转换为数字。


   const strNum = "25";
   const boolNum = true;
   const numFromString = Number(strNum);
   const numFromBool = Number(boolNum);
   console.log(numFromString); // 输出: 25
   console.log(numFromBool); // 输出: 1 (true为1,false为0)
   


4. **isNaN() 和 isFinite():** `isNaN()` 用于检查一个值是否为NaN,`isFinite()` 用于检查一个值是否为有限数值。


   console.log(isNaN(10)); // 输出: false
   console.log(isNaN("Hello")); // 输出: true
   console.log(isFinite(123)); // 输出: true
   console.log(isFinite(Infinity)); // 输出: false
   


5. **Math 对象:** 提供了许多用于数字操作的方法,比如:

   - `Math.round()`: 将数字四舍五入到最接近的整数。
   - `Math.floor()`: 返回小于或等于给定数字的最大整数。
   - `Math.ceil()`: 返回大于或等于给定数字的最小整数。
   - `Math.max()` 和 `Math.min()`: 返回一组数字中的最大值和最小值。
   - `Math.random()`: 返回一个介于 0(包括)到 1(不包括)之间的随机小数。
  
   console.log(Math.round(5.4)); // 输出: 5
   console.log(Math.floor(5.9)); // 输出: 5
   console.log(Math.ceil(5.1)); // 输出: 6
   console.log(Math.max(10, 20, 5)); // 输出: 20
   console.log(Math.min(10, 20, 5)); // 输出: 5
   console.log(Math.random()); // 输出: 介于 0 到 1 之间的随机小数
   


这些方法和函数可以帮助开发者在前端中对数字进行各种操作和转换。

`Math` 对象在 JavaScript 中提供了许多数学相关的方法。除了上述提到的一些常用方法外,还有一些其他有用的方法,以下是其中一些:
1. **Math.sqrt():** 返回一个数的平方根。


   const squareRoot = Math.sqrt(25);
   console.log(squareRoot); // 输出: 5
   


2. **Math.pow():** 返回一个数的指定次幂。

 
   const power = Math.pow(2, 3); // 2的3次幂
   console.log(power); // 输出: 8
   


3. **Math.abs():** 返回一个数的绝对值。


   const absoluteValue = Math.abs(-10);
   console.log(absoluteValue); // 输出: 10
   


4. **Math.sin()、Math.cos() 和 Math.tan():** 分别返回一个角的正弦、余弦和正切值(以弧度为单位)。


   const angleInRadians = Math.PI / 4; // 45度转换为弧度
   console.log(Math.sin(angleInRadians)); // 输出: 0.7071
   console.log(Math.cos(angleInRadians)); // 输出: 0.7071
   console.log(Math.tan(angleInRadians)); // 输出: 1
   


5. **Math.log() 和 Math.exp():** 分别返回一个数的自然对数和指数。


   const naturalLog = Math.log(Math.E); // 自然对数的底数是e,所以结果为1
   console.log(naturalLog); // 输出: 1
   const exponentialValue = Math.exp(2); // e的2次方
   console.log(exponentialValue); // 输出: 7.389
   


6. **Math.PI 和 Math.E:** 分别表示圆周率和自然对数的底数e。


   console.log(Math.PI); // 输出: 3.141592653589793
   console.log(Math.E); // 输出: 2.718281828459045
   


这些方法使得在 JavaScript 中进行数学计算更加便捷,开发者可以根据项目需求选择合适的方法。

19.时间对象常用方法

在前端开发中,处理时间是一个常见的任务。JavaScript 提供了 `Date` 对象来处理日期和时间。以下是 `Date` 对象常用的方法:
1. **获取当前时间:**


   const currentDate = new Date();
   console.log(currentDate); // 输出当前日期和时间
   


2. **获取特定日期和时间:**

  
   const specificDate = new Date("2023-01-01T12:00:00");
   console.log(specificDate); // 输出指定日期和时间
   


3. **获取年、月、日、时、分、秒:**


   const currentYear = currentDate.getFullYear();
   const currentMonth = currentDate.getMonth(); // 月份从 0 开始,所以需要加1
   const currentDay = currentDate.getDate();
   const currentHour = currentDate.getHours();
   const currentMinute = currentDate.getMinutes();
   const currentSecond = currentDate.getSeconds();
   console.log(currentYear, currentMonth + 1, currentDay, currentHour, currentMinute, currentSecond);
   


4. **格式化日期:**


   const options = { year: 'numeric', month: 'long', day: 'numeric' };
   const formattedDate = currentDate.toLocaleDateString('en-US', options);
   console.log(formattedDate); // 输出形如 "January 1, 2023" 的格式化日期
   


5. **设置日期和时间:**

  
   currentDate.setFullYear(2024);
   currentDate.setMonth(6); // 月份从 0 开始,所以 6 表示七月
   currentDate.setDate(15);
   currentDate.setHours(18);
   currentDate.setMinutes(30);
   currentDate.setSeconds(0);
   console.log(currentDate); // 输出更新后的日期和时间
   


6. **计算时间差:**


   const startDate = new Date("2023-01-01");
   const endDate = new Date("2023-12-31");
   const timeDifference = endDate - startDate; // 返回毫秒数
   const daysDifference = Math.floor(timeDifference / (24 * 60 * 60 * 1000)); // 转换为天数
   console.log(daysDifference); // 输出日期差
   


7. **获取当前时间戳:**

  
   const timestamp = currentDate.getTime(); // 返回当前时间的毫秒表示
   console.log(timestamp);
   


8. **其他方法:**

   - `getDay()`: 获取星期几,返回值是 0(星期日)到 6(星期六)。
   - `getUTCHours()`, `getUTCMinutes()`, 等:获取协调世界时(UTC)的小时、分钟等。
   - `toUTCString()`: 将日期转换为符合 UTC 格式的字符串。


这些方法可以帮助你在前端中处理和操作日期时间信息。

20.定时器

21.BOM

BOM(浏览器对象模型)提供了一组与浏览器窗口交互的对象和方法。以下是前端BOM的一些常见操作:
1. **窗口尺寸和位置:**

   - `window.innerWidth` 和 `window.innerHeight`: 获取浏览器窗口的内部宽度和高度。
   - `window.outerWidth` 和 `window.outerHeight`: 获取浏览器窗口的外部宽度和高度。
   - `window.screen.width` 和 `window.screen.height`: 获取屏幕的宽度和高度。
   - `window.screen.availWidth` 和 `window.screen.availHeight`: 获取屏幕可用的宽度和高度(去除任务栏等)。
   - `window.pageXOffset` 和 `window.pageYOffset`: 获取文档在水平和垂直方向上滚动的像素值。


2. **导航操作:**

   - `window.location`: 提供了当前文档的URL信息,可以通过 `window.location.href` 获取完整的URL。
   - `window.location.reload()`: 重新加载页面。
   - `window.location.href = "新的URL"`: 跳转到新的URL。
   - `window.history.back()` 和 `window.history.forward()`: 后退和前进浏览历史。
   - `window.history.go(n)`: 在浏览历史中移动 n 步。


3. **弹窗和对话框:**

   - `window.alert("消息")`: 弹出警告框。
   - `window.confirm("消息")`: 弹出确认框,返回用户点击的是确定还是取消。
   - `window.prompt("消息", "默认值")`: 弹出输入框,用户可以输入信息,返回输入的值。


4. **定时器:**

   - `window.setTimeout(function, delay)`: 在指定的毫秒数后执行一次函数。
   - `window.setInterval(function, interval)`: 每隔指定的毫秒数重复执行函数。
   - `window.clearTimeout(timerId)` 和 `window.clearInterval(intervalId)`: 清除定时器。


5. **屏幕操作:**

   - `window.open("URL", "窗口名称", "特性字符串")`: 打开新窗口。
   - `window.close()`: 关闭当前窗口。


6. **信息和日志:**

   - `console.log(message)`: 在控制台输出日志。
   - `console.warn(message)`: 输出警告信息。
   - `console.error(message)`: 输出错误信息。
   - `console.info(message)`: 输出一般信息。


7. **其他属性和方法:**

   - `window.navigator`: 提供浏览器相关信息,如用户代理(user agent)等。
   - `window.document`: 提供对文档对象的访问。
   - `window.localStorage` 和 `window.sessionStorage`: 提供本地存储和会话存储功能。
   - `window.onresize` 和 `window.onscroll`: 监听窗口大小变化和滚动事件。


这些操作使得开发者可以与浏览器窗口进行交互,实现更丰富的用户体验。

22.DOM

前端的 DOM(文档对象模型)操作允许开发者通过 JavaScript 访问、修改和控制网页的内容和结构。以下是一些常见的 DOM 操作:
1. **获取元素:**

   - `document.getElementById('id')`: 通过元素 ID 获取单个元素。
   - `document.getElementsByClassName('className')`: 通过类名获取一组元素。
   - `document.getElementsByTagName('tagName')`: 通过标签名获取一组元素。
   - `document.querySelector('selector')`: 使用 CSS 选择器获取单个元素。
   - `document.querySelectorAll('selector')`: 使用 CSS 选择器获取一组元素。


2. **操作元素内容和属性:**

   - `element.innerHTML`: 获取或设置元素的 HTML 内容。
   - `element.textContent`: 获取或设置元素的文本内容。
   - `element.setAttribute('attribute', 'value')`: 设置元素的属性值。
   - `element.getAttribute('attribute')`: 获取元素的属性值。
   - `element.style.property = 'value'`: 修改元素的 CSS 样式。
   - `element.classList.add/remove/toggle('className')`: 操作元素的类名。


3. **创建和添加元素:**

   - `document.createElement('tagName')`: 创建新元素。
   - `parentElement.appendChild(newElement)`: 将新元素添加到父元素中。
   - `parentElement.insertBefore(newElement, targetElement)`: 在指定元素之前插入新元素。


4. **事件处理:**

   - `element.addEventListener('event', function)`: 添加事件监听器。
   - `element.removeEventListener('event', function)`: 移除事件监听器。
   - 常见事件:`click`, `mouseover`, `submit`, `keydown` 等等。


5. **节点操作:**

   - `parentElement.removeChild(childElement)`: 删除子节点。
   - `node.parentNode`: 获取节点的父节点。
   - `node.childNodes`: 获取节点的所有子节点。
   - `node.firstChild` 和 `node.lastChild`: 获取第一个子节点和最后一个子节点。


6. **尺寸和位置:**

   - `element.offsetWidth` 和 `element.offsetHeight`: 获取元素的宽度和高度。
   - `element.getBoundingClientRect()`: 获取元素相对于视口的位置信息


7. **其他常用操作:**
 

  - `document.getElementById('id').focus()`: 让特定元素获得焦点。
   - `window.onload = function() { ... }`: 页面加载完成后执行特定操作。
   - `window.scroll(x-coord, y-coord)`: 滚动到页面的指定位置。


DOM 操作可以让开发者动态地修改页面内容和行为,实现与用户交互和更丰富的用户体验。

23.DOM节点

前端对 DOM 节点的操作主要涉及节点的创建、修改、删除等方面。以下是一些常见的 DOM 节点操作:
1. **创建节点:**

   - `document.createElement('tagName')`: 创建一个新的元素节点。
   - `document.createTextNode('text')`: 创建一个包含指定文本的文本节点。


2. **添加节点:**

   - `parentNode.appendChild(newNode)`: 将新节点添加为父节点的最后一个子节点。
   - `parentNode.insertBefore(newNode, referenceNode)`: 在父节点的指定子节点之前插入新节点。


3. **修改节点内容和属性:**

   - `node.textContent`:获取或设置节点的文本内容。
   - `node.innerHTML`:获取或设置节点的 HTML 内容。
   - `element.setAttribute('attribute', 'value')`: 设置节点的属性值。
   - `element.getAttribute('attribute')`: 获取节点的属性值。
   - `element.removeAttribute('attribute')`: 移除节点的指定属性。


4. **删除节点:**

   - `parentNode.removeChild(childNode)`: 从父节点中删除指定子节点。
   - `node.remove()`: 从其父节点中删除当前节点。


5. **复制节点:**
 

 - `node.cloneNode(true)`: 复制节点。如果参数为 true,会连同子节点一起复制。


6. **替换节点:**
 

  - `parentNode.replaceChild(newNode, oldNode)`: 用新节点替换父节点中的指定旧节点。


7. **遍历节点:**

   - `node.childNodes`: 获取节点的所有子节点(NodeList)。
   - `node.firstChild` 和 `node.lastChild`: 获取第一个子节点和最后一个子节点。
   - `node.nextSibling` 和 `node.previousSibling`: 获取同级的下一个和上一个节点。


8. **检查节点类型:**

   - `node.nodeType`: 获取节点类型。1 表示元素节点,3 表示文本节点,等等。
   - `node.nodeName` 和 `node.tagName`: 获取节点名称。


9. **判断节点关系:**

   - `node.parentNode`: 获取节点的父节点。
   - `node.hasChildNodes()`: 检查节点是否有子节点。
   - `node.contains(otherNode)`: 检查一个节点是否是另一个节点的后代。


10. **焦点和滚动:**

    - `element.focus()`: 让特定的元素获得焦点。
    - `element.scrollIntoView()`: 将元素滚动到可见区域。


这些节点操作方法使开发者能够动态地构建、修改和管理文档结构,实现灵活的前端交互。

24.js事件

1.初始事件

初始的 JavaScript 事件指的是页面加载时可能触发的事件。这些事件通常用于初始化页面或执行特定的操作。其中最常见的是 `DOMContentLoaded` 事件。
当浏览器完成解析文档时,会触发 `DOMContentLoaded` 事件。这表示 HTML 文档已完全加载和解析,但不包括样式表、图像等资源的加载。
在 JavaScript 中,可以通过以下方式添加 `DOMContentLoaded` 事件监听器:
使用 `addEventListener` 方法:


document.addEventListener('DOMContentLoaded', function(event) {
  // 在页面加载完成后执行的操作
});


或者直接将函数赋给 `DOMContentLoaded` 事件处理程序:


document.addEventListener('DOMContentLoaded', function(event) {
  // 在页面加载完成后执行的操作
});


这个事件非常有用,因为它允许你在页面加载后执行初始化代码,而无需等待所有资源(如图片)加载完成。这样可以提高用户体验,让页面更快地呈现内容或执行交互操作。

2.事件解绑

在 JavaScript 中,解绑(或移除)事件处理器有几种方法,具体取决于事件绑定的方式。以下是一些常见的解绑事件处理器的方法:
### 1. 使用 `removeEventListener` 方法:
如果事件是通过 `addEventListener` 方法添加的,可以使用 `removeEventListener` 方法来解绑事件处理器。确保解绑时传入相同的事件类型和处理函数。


// 添加事件处理器
element.addEventListener('click', myFunction);
// 移除事件处理器
element.removeEventListener('click', myFunction);


### 2. 直接将事件处理函数设为 `null`:
如果事件是通过直接将函数赋值给事件属性添加的,可以将相应事件属性设置为 `null` 来移除事件处理器。但请注意,这种方法仅适用于通过直接赋值添加的事件处理器。


// 添加事件处理器
element.onclick = myFunction;
// 移除事件处理器
element.onclick = null;


### 注意事项:
- 在使用 `removeEventListener` 移除事件处理器时,要确保传入的处理函数与添加时相同。否则,移除操作将无效。
- 如果事件处理器是通过匿名函数添加的,无法使用 `removeEventListener` 直接移除。在这种情况下,需要将匿名函数保存为变量,以便在移除时引用相同的函数。


// 添加匿名函数的事件处理器
var myHandler = function(event) {
  // 处理事件的代码
};
element.addEventListener('click', myHandler);
// 移除事件处理器
element.removeEventListener('click', myHandler);


通过这些方法,你可以有效地解绑事件处理器,确保不再监听特定的事件。

3.事件类型

JavaScript 支持多种事件类型,涵盖了用户与页面交互的各个方面。以下是一些常见的 JavaScript 事件类型:
1. **鼠标事件:**

   - `click`:单击鼠标按钮时触发。
   - `mousedown`:鼠标按钮被按下时触发。
   - `mouseup`:鼠标按钮被释放时触发。
   - `mousemove`:鼠标在元素内移动时触发。
   - `mouseover`:鼠标移入元素时触发。
   - `mouseout`:鼠标移出元素时触发。


2. **键盘事件:**

   - `keydown`:键盘按下时触发。
   - `keyup`:键盘释放时触发。
   - `keypress`:字符键被按下时触发。


3. **表单事件:**

   - `submit`:表单提交时触发。
   - `reset`:表单重置时触发。
   - `change`:输入字段的值发生改变并失去焦点时触发。
   - `input`:输入字段的值发生改变时触发(支持实时监听)。


4. **窗口事件:**

   - `load`:页面或图像加载完成时触发。
   - `unload`:页面即将被卸载时触发。
   - `resize`:窗口大小变化时触发。
   - `scroll`:滚动条滚动时触发。


5. **焦点事件:**

   - `focus`:元素获得焦点时触发。
   - `blur`:元素失去焦点时触发。


6. **事件传播相关:**

   - `mouseenter`:鼠标进入元素时触发,不冒泡。
   - `mouseleave`:鼠标离开元素时触发,不冒泡。
   - `stopPropagation()`:阻止事件冒泡。
   - `preventDefault()`:阻止事件的默认行为。


7. **移动端触摸事件:**

   - `touchstart`:触摸事件开始。
   - `touchmove`:触摸点在屏幕上移动。
   - `touchend`:触摸事件结束。
   - `touchcancel`:触摸事件被取消。


8. **其他事件:**

   - `animationstart`、`animationend`、`animationiteration`:CSS 动画相关事件。
   - `transitionstart`、`transitionend`:CSS 过渡相关事件。


这只是一部分常见的事件类型,JavaScript 还提供了更多的事件,以满足不同交互场景的需求。

4.事件对象

在 JavaScript 中,事件对象(Event Object)是在事件发生时传递给事件处理函数的对象,它包含了与事件相关的信息。事件对象提供了访问事件的属性和方法,以便在事件处理函数中获取有关事件的详细信息。
以下是事件对象常见的属性和方法:

1. **`event.type`:** 表示事件的类型,例如 `'click'`、`'keydown'` 等。
2. **`event.target`:** 表示触发事件的元素,即事件最初发生的元素。
3. **`event.currentTarget`:** 表示当前正在处理事件的元素,即事件处理函数被绑定的元素。
4. **`event.preventDefault()`:** 阻止事件的默认行为,例如阻止表单提交或超链接跳转。
5. **`event.stopPropagation()`:** 阻止事件的传播,停止事件在 DOM 树中的传递过程,即阻止事件冒泡。
6. **`event.keyCode` 和 `event.key`:** 用于键盘事件,分别表示按下键的键码和键值。
7. **`event.clientX` 和 `event.clientY`:** 用于鼠标事件,表示鼠标指针在视口中的水平和垂直坐标。
8. **`event.pageX` 和 `event.pageY`:** 用于鼠标事件,表示鼠标指针在文档中的水平和垂直坐标。
9. **`event.touches`:** 用于触摸事件,包含了触摸点的信息。
10. **`event.preventDefault()`:** 阻止事件的默认行为,例如阻止表单提交或超链接跳转。
在事件处理函数中,可以通过参数传递的方式获得事件对象,例如:

element.addEventListener('click', function(event) {
  console.log(event.type);         // 输出事件类型
  console.log(event.target);       // 输出触发事件的元素
  console.log(event.clientX);       // 输出鼠标在视口中的水平坐标
  event.preventDefault();          // 阻止默认行为
  event.stopPropagation();         // 阻止事件传播
});


通过事件对象,可以更灵活地处理和控制页面上发生的各种交互事件。

5.事件对象--鼠标事件

在处理鼠标事件时,事件对象提供了与鼠标交互相关的信息。以下是鼠标事件对象常见的属性:

1. **`event.clientX` 和 `event.clientY`:** 表示鼠标指针在视口中的水平和垂直坐标。
2. **`event.pageX` 和 `event.pageY`:** 表示鼠标指针在文档中的水平和垂直坐标。
3. **`event.screenX` 和 `event.screenY`:** 表示鼠标指针在屏幕中的水平和垂直坐标。
4. **`event.button`:** 表示按下或释放的鼠标按钮,其中左键是 0,中键是 1,右键是 2。
5. **`event.which`:** 与 `button` 类似,表示按下或释放的鼠标按钮。
6. **`event.type`:** 表示事件的类型,例如 `'click'`、`'mousedown'`、`'mouseup'`、`'mousemove'` 等。


通过这些属性,你可以获取鼠标事件的位置、按钮信息以及其他相关的属性。以下是一个示例,演示如何在鼠标点击时输出相关信息:


document.addEventListener('mousedown', function(event) {
  console.log('Mouse Down Event');
  console.log('ClientX: ' + event.clientX + ', ClientY: ' + event.clientY);
  console.log('PageX: ' + event.pageX + ', PageY: ' + event.pageY);
  console.log('ScreenX: ' + event.screenX + ', ScreenY: ' + event.screenY);
  console.log('Button: ' + event.button);
  console.log('Type: ' + event.type);
});


这样你可以根据需要使用这些信息来执行特定的操作,例如根据鼠标位置改变页面元素的样式或执行其他交互效果。

6.DOM事件流

DOM(文档对象模型)事件流描述的是在网页中,当事件(比如用户的点击、键盘输入等)发生时,它们被如何捕获和处理的过程。DOM事件流分为三个阶段:捕获阶段、目标阶段和冒泡阶段。
1. **捕获阶段(Capturing Phase):**
   - 事件从文档的根节点向下传播到目标元素。
   - 在捕获阶段,事件首先经过文档树上的最外层元素,然后逐级向下传递,直到达到触发事件的目标元素。
2. **目标阶段(Target Phase):**
   - 事件达到目标元素。
   - 事件在目标元素上触发,如果事件是冒泡型(大多数事件都是),则进入冒泡阶段。
3. **冒泡阶段(Bubbling Phase):**
   - 事件从目标元素向上冒泡到文档的根节点。
   - 在冒泡阶段,事件从触发它的目标元素开始,逐级向上传递到文档树的最外层元素。
在实际应用中,事件流可以通过事件处理程序来进行控制。通过添加捕获阶段和冒泡阶段的事件监听器,开发者可以决定在哪个阶段执行相应的代码。在大多数情况下,事件处理程序会在冒泡阶段执行,因为这样更符合直觉和常见的需求。
以下是一个简单的JavaScript代码示例,演示了如何使用addEventListener来监听事件流的不同阶段:


var element = document.getElementById("myElement");
// 捕获阶段
element.addEventListener("click", function(event) {
    console.log("捕获阶段");
}, true);
// 冒泡阶段
element.addEventListener("click", function(event) {
    console.log("冒泡阶段");
}, false);


在上述代码中,第三个参数用于指定事件处理程序是在捕获阶段(true)还是冒泡阶段(false)执行。

7.阻止事件传播

要阻止事件传播,可以使用事件对象的 `stopPropagation()` 方法。这个方法可以在事件处理程序中调用,以阻止事件在捕获阶段或冒泡阶段继续传播。
以下是一个简单的示例,演示如何在点击按钮时阻止事件传播:
 


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>阻止事件传播示例</title>
</head>
<body>
<div id="outer" style="border: 1px solid #000; padding: 10px;">
  <p>外层容器</p>
  <button id="inner">内部按钮</button>
</div>
<script>
document.getElementById("outer").addEventListener("click", function() {
  console.log("外层容器被点击");
});
document.getElementById("inner").addEventListener("click", function(event) {
  console.log("内部按钮被点击");
  // 阻止事件传播
  event.stopPropagation();
});
</script>
</body>
</html>

8.阻止默认事件

要阻止事件的默认行为,可以使用事件对象的 `preventDefault()` 方法。这个方法可以在事件处理程序中调用,以防止事件的默认行为发生。
以下是一个简单的示例,演示如何在点击链接时阻止默认的跳转行为:
 


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>阻止默认行为示例</title>
</head>
<body>
<a href="https://www.example.com" id="myLink">点击我</a>
<script>
document.getElementById("myLink").addEventListener("click", function(event) {
  console.log("链接被点击");
  // 阻止默认行为
  event.preventDefault();
});
</script>
</body>
</html>

9.事件委托

事件委托是一种优化事件处理的方法,通过将事件处理程序添加到父元素而不是每个子元素上,从而减少事件处理程序的数量。这对于处理大量相似子元素的情况特别有用。
以下是一个简单的例子,演示如何使用事件委托:
 


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>事件委托示例</title>
  <style>
    ul {
      list-style: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 5px;
      padding: 10px;
      border: 1px solid #ccc;
      cursor: pointer;
    }
  </style>
</head>
<body>
<ul id="parentList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <!-- More items... -->
</ul>
<script>
document.getElementById("parentList").addEventListener("click", function(event) {
  // 使用事件委托处理子元素的点击事件
  if (event.target.tagName === "LI") {
    console.log("点击了子元素:" + event.target.textContent);
  }
});
</script>
</body>
</html>

25.js正则知识点

1.认识正则

JavaScript中的正则表达式是用于匹配和操作字符串的强大工具。它们由模式和修饰符组成,可以用来搜索、替换和提取字符串中的特定部分。
以下是JavaScript中正则表达式的基本用法和一些常见的正则表达式模式及其含义:
### 创建正则表达式
在JavaScript中,你可以通过两种方式创建正则表达式:
1. **字面量方式:** 使用斜杠符号将模式包含在两个斜杠之间。

   - 示例:`/pattern/`


   
2. **构造函数方式:** 使用`RegExp`构造函数来创建正则表达式对象。
   - 示例:`new RegExp("pattern")`
### 常见的正则表达式模式

- **字符匹配:**
  - `\d`: 匹配数字字符。
  - `\w`: 匹配字母、数字或下划线字符。
  - `\s`: 匹配空白字符,包括空格、制表符等。
  - `.`: 匹配除换行符之外的任意字符。
  - `[]`: 匹配方括号内的任意字符。
- **重复匹配:**
  - `*`: 匹配前一个元素零次或多次。
  - `+`: 匹配前一个元素一次或多次。
  - `?`: 匹配前一个元素零次或一次。
  - `{n}`: 匹配前一个元素恰好 n 次。
  - `{n,}`: 匹配前一个元素至少 n 次。
  - `{n,m}`: 匹配前一个元素至少 n 次,最多 m 次。
- **位置匹配:**
  - `^`: 匹配输入的开始。
  - `$`: 匹配输入的结束。
- **其他:**
  - `|`: 或操作,匹配多个模式中的一个。
  - `()`: 分组匹配,用于捕获子模式。
### 正则表达式的修饰符
- `g`: 全局匹配,查找所有匹配项。
- `i`: 不区分大小写匹配。
- `m`: 多行匹配。


在JavaScript中,正则表达式可以与字符串的方法一起使用,如`test()`、`match()`、`replace()`等,以执行不同的操作。通过组合不同的模式和修饰符,可以实现灵活强大的字符串处理功能。

2.元字符--基本元字符

元字符是正则表达式中具有特殊含义的字符,它们用于构建匹配规则。基本元字符是最简单的元字符,它们表示它们本身,而不是任何特殊含义。以下是一些常见的基本元字符:

1. **字面量字符:**
   - 字母、数字、标点符号等通常表示它们自身。例如,字母 "a" 表示字母 "a"。
2. **转义字符 `\`:**
   - 如果想匹配正则表达式中的特殊字符,可以使用反斜杠 `\` 进行转义。例如,`\.` 表示匹配实际的点号而不是点号的特殊含义。
3. **点号 `.`:**
   - 表示匹配任意单个字符,除了换行符。
4. **字符类 `[ ]`:**
   - 字符类用于匹配方括号内的任意一个字符。例如,`[aeiou]` 可以匹配任何一个元音字母。
5. **脱字符 `^`:**
   - 在字符类内,`^` 表示取反,即匹配不在字符类内的字符。例如,`[^0-9]` 表示匹配任何非数字字符。
6. **连字符 `-`:**
   - 在字符类内,表示一个范围。例如,`[0-9]` 表示匹配任何数字。
7. **反斜杠 `\`:**
   - 用于转义下一个字符,或表示一些特殊的元字符。例如,`\d` 表示匹配任何数字字符。
8. **反向斜杠 `/`:**
   - 在某些环境中,用于标识正则表达式的开始或结束。


这些基本元字符是构建更复杂正则表达式的基础。通过组合它们,可以创建灵活的模式来匹配字符串中的特定文本。

3.元字符-边界符

在JavaScript中,正则表达式中的元字符和边界符具有特殊的含义,用于匹配字符串中的特定模式。以下是一些常用的元字符和边界符:
### 元字符

1. **`.` (点)**:匹配除换行符之外的任何单个字符。
   - `/a.b/` 可以匹配 "a1b"、"a@b" 等。
2. **`^` (脱字符)**:匹配字符串的开始位置。
   - `/^a/` 可以匹配 "apple" 中的 "a"。
3. **`$` (美元符)**:匹配字符串的结束位置。
   - `/e$/` 可以匹配 "apple" 中的 "e"。
4. **`*` (星号)**:匹配前面的元素零次或多次。
   - `/a*b/` 可以匹配 "ab"、"aab"、"aaab" 等。
5. **`+` (加号)**:匹配前面的元素一次或多次。
   - `/a+b/` 可以匹配 "ab"、"aab"、但不能匹配 "b"。
6. **`?` (问号)**:匹配前面的元素零次或一次。
   - `/a?b/` 可以匹配 "ab" 和 "b"。
7. **`\` (反斜线)**:用于转义下一个字符,使其失去特殊含义。
   - `/a\.b/` 可以匹配 "a.b"。
### 边界符
1. **`\b`**:匹配单词的边界。一个单词边界是一个单词字符和一个非单词字符之间的位置。
   - `/\bcat\b/` 可以匹配 "cat",但不匹配 "catapult"。
2. **`\B`**:匹配非单词边界。
   - `/cat\B/` 可以匹配 "catapult",但不匹配 "cat"。


这些元字符和边界符在正则表达式中扮演了关键的角色,用于创建更为灵活和准确的模式匹配规则。

4.元字符-限定符

在正则表达式中,限定符用于指定匹配的数量或范围。以下是一些常用的元字符中的限定符:

1. **`*` (星号)**:匹配前面的元素零次或多次。
   - `/a*b/` 可以匹配 "ab"、"aab"、"aaab" 等。
2. **`+` (加号)**:匹配前面的元素一次或多次。
   - `/a+b/` 可以匹配 "ab"、"aab",但不能匹配 "b"。
3. **`?` (问号)**:匹配前面的元素零次或一次。
   - `/a?b/` 可以匹配 "ab" 和 "b"。
4. **`{n}`**:匹配前面的元素恰好出现 n 次。
   - `/a{3}b/` 可以匹配 "aaab"。
5. **`{n,}`**:匹配前面的元素至少出现 n 次。
   - `/a{2,}b/` 可以匹配 "aab"、"aaab" 等。
6. **`{n,m}`**:匹配前面的元素出现 n 到 m 次。
   - `/a{2,4}b/` 可以匹配 "aab"、"aaab"、"aaaab" 等。


这些限定符允许你更灵活地定义模式的重复次数,使正则表达式更强大和通用。请注意,限定符通常应用于前面的元素,例如字符、字符集或分组。 

 5.元字符-特殊符号

在正则表达式中,一些特殊符号具有特殊的含义,称为元字符。这些元字符用于表示匹配规则的特殊字符或位置。以下是一些常见的元字符特殊符号:

1. **`.` (点)**:匹配除换行符之外的任何单个字符。
2. **`^` (脱字符)**:匹配字符串的开始位置。
3. **`$` (美元符)**:匹配字符串的结束位置。
4. **`*` (星号)**:匹配前面的元素零次或多次。
5. **`+` (加号)**:匹配前面的元素一次或多次。
6. **`?` (问号)**:匹配前面的元素零次或一次。
7. **`\` (反斜线)**:用于转义下一个字符,使其失去特殊含义。
8. **`[]` (字符集)**:匹配方括号内的任何一个字符。
   - `/[aeiou]/` 可以匹配任何一个元音字母。
9. **`[^]` (否定字符集)**:匹配除了方括号内的字符之外的任何字符。
   - `/[^0-9]/` 可以匹配任何非数字字符。
10. **`|` (管道符)**:用于在模式中创建一个或的关系,匹配两者之一。
    - `/cat|dog/` 可以匹配 "cat" 或 "dog"。
11. **`()`` (捕获组)**:用于捕获匹配的子字符串,以便后续引用。
    - `/(\d+)-(\d+)/` 可以匹配 "123-456" 并捕获两个数字。


这些元字符特殊符号在构建复杂的匹配规则时非常有用,允许你指定更灵活和精确的模式。请注意使用转义符 `\` 来处理特殊字符,或者将其放在字符集中以失去特殊含义。 

6.正则表达式捕获-exec 

正则表达式的捕获是指通过正则表达式匹配的文本中提取特定部分的过程。在JavaScript中,`exec` 方法是用于执行正则表达式匹配的方法,并返回一个包含匹配信息的数组。
以下是使用 `exec` 方法进行正则表达式捕获的基本示例:


// 创建正则表达式模式
const pattern = /(\d+)-(\d+)/;
// 要匹配的文本
const text = "123-456";
// 使用 exec 方法进行匹配
const result = pattern.exec(text);
// result 是一个数组,包含匹配的信息
if (result) {
  const fullMatch = result[0];    // 完整匹配结果 "123-456"
  const group1 = result[1];       // 第一个捕获组 "123"
  const group2 = result[2];       // 第二个捕获组 "456"
  console.log("完整匹配:", fullMatch);
  console.log("捕获组1:", group1);
  console.log("捕获组2:", group2);
} else {
  console.log("未匹配到任何内容");
}


在这个例子中,正则表达式模式 `(\d+)-(\d+)` 包含两个捕获组,分别匹配连续的数字。`exec` 方法返回一个数组,其中第一个元素是完整的匹配结果,后续元素是捕获组的内容。
请注意,每次调用 `exec` 方法都会在文本中继续查找下一个匹配项。当没有更多匹配项时,`exec` 返回 `null`。
需要注意的是,正则表达式的捕获也可以使用字符串的 `match` 方法,不过它返回的数组结构稍有不同。

7.正则二大特性

正则表达式有两个主要特性,它们是:
1. **模式匹配:** 正则表达式用于描述字符串的模式,可以帮助你在文本中查找符合特定模式的字符串。通过使用不同的元字符和语法规则,你可以创建灵活的模式,以匹配特定的文本模式。例如,使用正则表达式可以轻松地匹配邮箱地址、日期、数字等。
   示例:
   - 匹配邮箱地址的正则表达式:`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
2. **字符操作:** 正则表达式不仅可以用于查找文本,还可以进行字符操作,如替换、提取和拆分。通过使用正则表达式中的捕获组和替换模式,你可以对匹配的文本进行操作,实现灵活的文本处理任务。
   示例:
   - 使用正则表达式替换文本中的日期格式:`(\d{4})-(\d{2})-(\d{2})` 替换为 `$3/$2/$1`
总体而言,正则表达式是一种强大的文本处理工具,它在处理各种文本操作和搜索任务中都能发挥重要作用。

26.this介绍

JavaScript中的`this`是一个关键字,它的值在函数被调用时确定。`this`的指向在不同的情境下可能会有所不同。
1. **全局上下文中的`this`:**
   在全局上下文中,`this`指向全局对象,通常是`window`对象(浏览器环境)。


   console.log(this === window); // 输出: true
   


2. **函数中的`this`:**
   在函数中,`this`的值取决于函数是如何被调用的。
   - **普通函数调用:** `this`通常指向全局对象。


     function exampleFunction() {
       console.log(this);
     }
     exampleFunction(); // 在浏览器中输出: window
     


   - **作为对象方法调用:** `this`指向调用该方法的对象。


     let obj = {
       prop: 'I am an object property',
       logProp: function() {
         console.log(this.prop);
       }
     };
     obj.logProp(); // 输出: I am an object property

   - **使用`call`、`apply`或`bind`方法:** 这些方法允许手动设置函数内部的`this`值。
  
     function greet(name) {
       console.log(`Hello, ${name}! My name is ${this.name}.`);
     }
     let person = { name: 'John' };
     greet.call(person, 'Alice'); // 输出: Hello, Alice! My name is John.
     


3. **构造函数中的`this`:**
   当使用`new`关键字调用构造函数创建对象时,`this`指向新创建的对象。


   function Person(name) {
     this.name = name;
   }
   let person = new Person('John');
   console.log(person.name); // 输出: John
   


4. **箭头函数中的`this`:**
   箭头函数没有自己的`this`,它会捕获外部的`this`值。


   let exampleObject = {
     value: 42,
     getValue: function() {
       return () => {
         console.log(this.value);
       };
     }
   };
   let getFn = exampleObject.getValue();
   getFn(); // 输出: 42
   


理解`this`的指向是JavaScript中面向对象编程的重要一环,因为它影响了函数内部的代码在不同上下文中的行为。

27.ES6

1.初步认识

ES6,也称为ECMAScript 2015,是JavaScript的第六个版本,于2015年发布。它引入了许多新的语言特性和增强,以提高JavaScript的可读性、可维护性和功能性。以下是ES6引入的一些主要特性:
1. **let 和 const 声明:**
   - 引入了 `let` 和 `const` 关键字,用于声明变量。`let` 声明的变量可以被重新赋值,而 `const` 声明的变量是常量,不能被重新赋值。


   let x = 10;
   const PI = 3.14;
   


2. **箭头函数:**
   - 箭头函数是一种更简洁的函数定义方式,具有更短的语法和词法作用域。


   // 传统函数
   function add(a, b) {
     return a + b;
   }
   // 箭头函数
   const add = (a, b) => a + b;
   


3. **模板字符串:**
   - 模板字符串允许在字符串中嵌入变量,使用反引号(`)括起来。


   let name = "John";
   let greeting = `Hello, ${name}!`;
   


4. **解构赋值:**
   - 解构赋值允许从数组或对象中提取值,并将它们分配给变量。

  
   // 数组解构
   const [a, b] = [1, 2];
   // 对象解构
   const { x, y } = { x: 1, y: 2 };
   


5. **类和继承:**
   - 引入了类和继承的概念,使面向对象编程更加直观和方便。

  
   class Animal {
     constructor(name) {
       this.name = name;
     }
     speak() {
       console.log(`${this.name} makes a sound.`);
     }
   }
   class Dog extends Animal {
     speak() {
       console.log(`${this.name} barks.`);
     }
   }
   const dog = new Dog("Buddy");
   dog.speak(); // 输出: Buddy barks.
   


6. **模块化:**
   - 引入了模块化系统,允许将代码分割为小的、独立的模块,提高代码的组织性和可维护性。


   // 导出模块
   export const PI = 3.14;
   // 导入模块
   import { PI } from './math';
  


7. **Promise 对象:**
   - Promise 是一种处理异步操作的方式,使得异步代码更加可读和易于管理。


   const fetchData = () => {
     return new Promise((resolve, reject) => {
       // 异步操作
       if (/* 操作成功 */) {
         resolve(data);
       } else {
         reject(error);
       }
     });
   };
   


这些是ES6引入的一些主要特性,它们为JavaScript开发者提供了更强大和灵活的工具,改进了语言的表达能力和开发体验。

2.ES6定义变量

在ES6(ECMAScript 2015)中,引入了两个新的变量声明关键字:`let` 和 `const`。它们改变了在JavaScript中声明变量的方式,并提供了更灵活和可控的变量声明方式。以下是对这两个关键字的详细讲解:
### 1. let 关键字
`let` 关键字用于声明一个变量,其作用域限定在块级作用域内,例如在 `{}` 内部。与 `var` 不同,`let` 不会在整个函数内部产生变量提升,而是在声明的位置之前不可访问。
**示例:**


function example() {
  if (true) {
    let x = 10; // 只在这个块级作用域内有效
    console.log(x); // 输出 10
  }
  // console.log(x); // 在这里访问 x 会导致 ReferenceError,因为 x 不在这个作用域内
}


### 2. const 关键字
`const` 关键字用于声明一个常量,其值在声明后不能被重新赋值。与 `let` 不同,`const` 必须在声明时进行初始化,而且一旦初始化就不能再改变。
**示例:**


const PI = 3.14;
// PI = 3; // 尝试重新赋值会导致错误
const person = {
  name: "John",
  age: 30
};
// person = {}; // 尝试重新赋值会导致错误
person.age = 31; // 但可以修改对象的属性值
console.log(person); // 输出: { name: 'John', age: 31 }


### 3. 块级作用域
使用 `let` 和 `const` 可以创建块级作用域,这在处理循环、条件语句等场景时非常有用,避免了变量污染全局作用域。
**示例:**


function example() {
  let i = 0;
  for (let i = 0; i < 5; i++) {
    console.log(i); // 输出 0, 1, 2, 3, 4
  }
  console.log(i); // 输出 0,因为块级作用域内的 i 不影响外部的 i
}


总体而言,`let` 和 `const` 提供了更好的变量声明方式,能够更好地控制变量的作用域和可变性,使代码更加健壮和可读。

3.ES6箭头函数

ES6引入了箭头函数,它是一种更简洁的函数定义方式,具有更短的语法和词法作用域。箭头函数可以更清晰地定义函数表达式,并且改变了 `this` 的指向。
### 箭头函数的语法:


// 传统函数
function add(a, b) {
  return a + b;
}
// 箭头函数
const add = (a, b) => a + b;


箭头函数相比传统函数有以下特点:
1. **简洁的语法:** 当函数体只有一条语句时,可以省略花括号 `{}` 和 `return` 关键字。
2. **词法作用域的 this:** 箭头函数没有自己的 `this`,它会捕获所在上下文的 `this` 值,解决了传统函数中 `this` 指向的问题。
### 示例:


// 传统函数
function greet(name) {
  return "Hello, " + name + "!";
}
// 箭头函数
const greet = name => "Hello, " + name + "!";


在处理回调函数或简单函数时,箭头函数可以使代码更加简洁易懂。
### 使用箭头函数处理数组方法:


const numbers = [1, 2, 3, 4, 5];
// 传统函数
const doubled = numbers.map(function (number) {
  return number * 2;
});
// 箭头函数
const doubled = numbers.map(number => number * 2);


### 注意事项:


1. **没有自己的 this:** 箭头函数内部的 `this` 指向是固定的,由外围最近一层非箭头函数决定。
2. **不适用于构造函数:** 不能用作构造函数,不具有 `new` 关键字的功能。
3. **没有 `arguments` 对象:** 箭头函数没有自己的 `arguments` 对象,但可以使用 rest 参数 `...args` 来获取参数。
箭头函数是ES6中非常实用和便捷的特性,尤其适用于简单函数和解决传统函数中 `this` 指向混乱的问题。

4.ES6解构赋值

ES6解构赋值是JavaScript中的一种特性,用于从数组或对象中提取数据并赋值给变量,使得赋值操作更简洁和灵活。
### 数组解构赋值
在数组解构赋值中,可以通过模式匹配的方式将数组中的值赋给对应的变量。例如:


// 数组解构赋值示例
const numbers = [1, 2, 3, 4, 5];
// 从数组中提取值并赋给变量
const [a, b, , c] = numbers;
console.log(a); // 输出: 1
console.log(b); // 输出: 2
console.log(c); // 输出: 4


### 对象解构赋值
对象解构赋值允许直接从对象中提取属性值并赋给对应的变量。示例如下:


// 对象解构赋值示例
const person = {
  name: 'Alice',
  age: 30,
  country: 'USA'
};
// 从对象中提取属性值并赋给变量
const { name, age, country } = person;
console.log(name); // 输出: 'Alice'
console.log(age); // 输出: 30
console.log(country); // 输出: 'USA'


### 嵌套解构赋值
在ES6中,解构赋值还支持嵌套结构,可以从嵌套的数组或对象中提取值。例如:


// 嵌套解构赋值示例
const nestedArray = [1, [2, 3], 4];
const [x, [y, z], w] = nestedArray;
console.log(x); // 输出: 1
console.log(y); // 输出: 2
console.log(z); // 输出: 3
console.log(w); // 输出: 4
```
```javascript
// 嵌套对象解构赋值示例
const nestedObject = {
  outer: {
    inner: {
      value: 'Nested value'
    }
  }
};
const { outer: { inner: { value } } } = nestedObject;
console.log(value); // 输出: 'Nested value'


ES6解构赋值为JavaScript中的数据提取和赋值操作提供了更灵活和简洁的方式,可以帮助编写更清晰、更易读的代码。

5.ES6对象简写

ES6对象简写是指在创建对象字面量时,可以更简洁地书写属性和方法的语法。以下是一些ES6对象简写的示例:
### 1. 属性简写
在对象字面量中,如果属性名和变量名相同,可以省略属性名,只写变量名。示例如下:


// 属性简写示例
const name = 'John';
const age = 25;
// 使用属性简写创建对象
const person = { name, age };
console.log(person);
// 输出: { name: 'John', age: 25 }


### 2. 方法简写
在对象字面量中,如果一个属性是一个函数,可以使用方法简写的方式定义函数。示例如下:


// 方法简写示例
const calculator = {
  add(x, y) {
    return x + y;
  },
  subtract(x, y) {
    return x - y;
  }
};
console.log(calculator.add(5, 3)); // 输出: 8
console.log(calculator.subtract(8, 3)); // 输出: 5


### 3. 动态属性名
在对象字面量中,可以使用方括号和表达式来定义动态属性名。示例如下:


// 动态属性名示例
const dynamicKey = 'color';
// 使用动态属性名创建对象
const car = {
  brand: 'Toyota',
  [dynamicKey]: 'blue'
};
console.log(car);
// 输出: { brand: 'Toyota', color: 'blue' }


ES6对象简写使得创建和定义对象变得更加简便和清晰,提高了代码的可读性。

6.ES6展开运算符

ES6的展开运算符允许在某些情况下展开数组或对象,并在另一个数组或对象中使用这些值。它提供了一种简洁的方式来合并数组,复制数组或对象,并在函数调用中传递多个参数。
### 数组展开运算符
在数组中,展开运算符可以用于展开另一个数组的值。示例如下:


// 数组展开运算符示例
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];
console.log(arr2);
// 输出: [1, 2, 3, 4, 5, 6]


### 对象展开运算符
在对象中,展开运算符可以用于复制对象,并添加或覆盖属性。示例如下:


// 对象展开运算符示例
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3, d: 4 };
console.log(obj2);
// 输出: { a: 1, b: 2, c: 3, d: 4 }


### 函数调用中的展开运算符
在函数调用中,展开运算符可以将数组中的值作为参数传递给函数。示例如下:


// 函数调用中的展开运算符示例
function sum(a, b, c) {
  return a + b + c;
}
const numbers = [1, 2, 3];
const result = sum(...numbers);
console.log(result);
// 输出: 6


展开运算符提供了一种便捷的方式来操作数组和对象,使得在JavaScript中处理数据更加灵活和方便。

7.ES6模块化语法

ES6引入了模块化语法,使得 JavaScript 中的代码可以更好地组织和管理。模块化有助于将代码拆分成可维护和可重用的小块,同时提供了更好的命名空间管理。以下是ES6模块化语法的基本要点:
### 导出(Export)
#### 1. 默认导出
通过 `export default` 关键字可以指定模块的默认导出。一个模块只能有一个默认导出。


// module.js
const name = 'John';
export default name;


在另一个文件中使用默认导出:


// anotherModule.js
import defaultName from './module';
console.log(defaultName); // 输出: 'John'


#### 2. 命名导出
使用 `export` 关键字可以命名导出一个或多个变量、函数或类。


// module.js
export const num1 = 42;
export const num2 = 23;
export function add(a, b) {
  return a + b;
}


在另一个文件中使用命名导出:


// anotherModule.js
import { num1, num2, add } from './module';
console.log(num1); // 输出: 42
console.log(num2); // 输出: 23
console.log(add(5, 7)); // 输出: 12


### 导入(Import)
使用 `import` 关键字可以导入模块中的内容。


// main.js
import defaultName from './module';
import { num1, num2, add } from './anotherModule';
console.log(defaultName); // 输出: 'John'
console.log(num1); // 输出: 42
console.log(num2); // 输出: 23
console.log(add(5, 7)); // 输出: 12


### 别名导入
可以使用 `as` 关键字给导入的变量起一个别名。


// main.js
import { num1 as firstNumber, num2 as secondNumber, add as sum } from './anotherModule';
console.log(firstNumber); // 输出: 42
console.log(secondNumber); // 输出: 23
console.log(sum(5, 7)); // 输出: 12


ES6模块化语法使得 JavaScript 代码更易维护、组织,同时提高了代码的可重用性和可读性。

28.面向对象

在JavaScript中,面向对象编程(Object-Oriented Programming,简称OOP)是一种常见的编程范式。以下是在JavaScript中初始阶段使用面向对象编程的一些建议和基本概念:
### 1. 对象创建与属性
在JavaScript中,你可以使用对象字面量语法创建对象:


// 创建一个空对象
let myObject = {};
// 创建带有属性的对象
let person = {
  name: 'John',
  age: 30,
  greet: function() {
    console.log('Hello, I am ' + this.name + '!');
  }
};
// 访问属性和调用方法
console.log(person.name);  // 输出: John
person.greet();            // 输出: Hello, I am John!


### 2. 构造函数和实例化
使用构造函数可以创建对象的模板,然后通过 `new` 关键字实例化对象:


// 构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log('Hello, I am ' + this.name + '!');
  };
}
// 实例化对象
let person1 = new Person('John', 30);
let person2 = new Person('Alice', 25);
// 访问属性和调用方法
console.log(person1.name);   // 输出: John
person1.greet();             // 输出: Hello, I am John!
console.log(person2.name);   // 输出: Alice
person2.greet();             // 输出: Hello, I am Alice!


### 3. 原型链和原型继承
JavaScript使用原型链实现继承。每个对象都有一个指向其原型的引用,可以通过原型链访问原型的属性和方法:


// 构造函数
function Animal(name) {
  this.name = name;
}
// 在原型上定义方法
Animal.prototype.makeSound = function() {
  console.log('Some generic sound');
};
// 继承
function Dog(name, breed) {
  Animal.call(this, name); // 调用父类构造函数
  this.breed = breed;
}
// 设置原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 在子类上定义方法
Dog.prototype.bark = function() {
  console.log('Woof! Woof!');
};
// 实例化对象
let myDog = new Dog('Buddy', 'Golden Retriever');
// 访问属性和调用方法
console.log(myDog.name);      // 输出: Buddy
myDog.makeSound();             // 输出: Some generic sound
myDog.bark();                  // 输出: Woof! Woof!


以上是JavaScript中面向对象编程的一些基本概念。随着学习的深入,你还可以了解更多高级的面向对象概念,例如封装、多态和抽象类。

1.创建对象的方式

在JavaScript中,有多种方式来创建对象。以下是一些常见的创建对象的方式:
### 1. 对象字面量
使用对象字面量直接定义对象:


let person = {
  name: 'John',
  age: 30,
  greet: function() {
    console.log('Hello, I am ' + this.name + '!');
  }
};

### 2. 构造函数
使用构造函数创建对象,可以通过 `new` 关键字实例化对象:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log('Hello, I am ' + this.name + '!');
  };
}
let person = new Person('John', 30);


### 3. Object 构造函数
使用 `Object` 构造函数创建对象:


let person = new Object();
person.name = 'John';
person.age = 30;
person.greet = function() {
  console.log('Hello, I am ' + this.name + '!');
};

### 4. Object.create()
使用 `Object.create()` 方法创建对象,并指定原型对象:

let personPrototype = {
  greet: function() {
    console.log('Hello, I am ' + this.name + '!');
  }
};
let person = Object.create(personPrototype);
person.name = 'John';
person.age = 30;

### 5. 类(ES6+)
使用类的方式创建对象(ES6及以上版本):

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  greet() {
    console.log('Hello, I am ' + this.name + '!');
  }
}
let person = new Person('John', 30);


以上是一些常见的创建对象的方式。选择哪种方式取决于你的需求和个人偏好。在现代JavaScript中,使用类是一种更常见的方式,特别是在面向对象编程方面。

2.构造函数注意的问题

在JavaScript中使用构造函数创建对象时,有一些注意的问题需要考虑:
1. **使用 `new` 关键字:** 构造函数需要使用 `new` 关键字来实例化对象。如果忘记使用 `new`,可能会导致意外的行为或错误。


   // 错误的示例,忘记使用 new
   function Person(name, age) {
     this.name = name;
     this.age = age;
   }
   // 正确的示例
   let person = new Person('John', 30);
   


2. **每个实例都有独立的方法:** 如果在构造函数中定义方法,每个实例都将拥有独立的方法副本。这可能会导致内存浪费,尤其是在大量实例化的情况下。


   function Person(name) {
     this.name = name;
     this.greet = function() {
       console.log('Hello, I am ' + this.name + '!');
     };
   }
   let person1 = new Person('John');
   let person2 = new Person('Alice');
   // person1 和 person2 的 greet 方法是独立的
   console.log(person1.greet === person2.greet); // false
   


   为了避免这个问题,可以将方法放在构造函数外部,使用原型链来共享方法。
3. **原型链和继承:** 如果使用构造函数来创建对象,并且希望实现继承关系,需要正确设置原型链。这样才能确保子类能够访问父类的方法。


   function Animal(name) {
     this.name = name;
   }
   function Dog(name, breed) {
     Animal.call(this, name); // 调用父类构造函数
     this.breed = breed;
   }
   // 设置原型链
   Dog.prototype = Object.create(Animal.prototype);
   Dog.prototype.constructor = Dog;
   


   这样,`Dog` 类就能够继承 `Animal` 类的属性和方法。
4. **构造函数内的变量作用域:** 在构造函数内部声明的变量是局部变量,只在构造函数内部可见。如果希望在实例中共享某个值,应将其作为属性添加到 `this` 对象上。

  
   function Counter() {
     let count = 0; // 局部变量
     this.increment = function() {
       count++;
     };
     this.getCount = function() {
       return count;
     };
   }
   let counter1 = new Counter();
   let counter2 = new Counter();
   counter1.increment();
   console.log(counter1.getCount()); // 输出: 1
   counter2.increment();
   console.log(counter2.getCount()); // 输出: 1,因为 count 是局部变量
   


   如果希望 `count` 在所有实例中共享,应该将其定义为属性:`this.count = 0;`。
考虑这些注意事项,可以更有效地使用构造函数创建对象,并确保代码的可读性和维护性。

3.面向对象的原型

在JavaScript中,原型(prototype)是面向对象编程中一个重要的概念。每个对象都有一个原型,它是一个指向另一个对象的引用,从而形成了一个原型链。原型链的最终点是null。让我们深入了解一下面向对象的原型在JavaScript中的作用和使用方法。
### 1. **构造函数和原型对象**
在JavaScript中,每个函数都有一个与之关联的原型对象(prototype object)。当你创建一个函数时,它会自动获得一个名为 "prototype" 的属性,该属性指向一个空对象。


function Person(name, age) {
  this.name = name;
  this.age = age;
}
// Person 函数的原型对象
console.log(Person.prototype); // 输出: {}


### 2. **原型对象的用途**
原型对象的主要作用是共享方法。所有通过构造函数实例化的对象,都可以访问原型对象上定义的方法。


Person.prototype.greet = function() {
  console.log('Hello, I am ' + this.name + '!');
};
let person1 = new Person('John', 30);
let person2 = new Person('Alice', 25);
person1.greet(); // 输出: Hello, I am John!
person2.greet(); // 输出: Hello, I am Alice!


这样做的好处是,不必为每个实例都创建一个独立的 `greet` 方法,从而节省内存。
### 3. **原型链**
原型链是由对象的原型组成的链,它决定了对象的属性和方法的访问顺序。当试图访问对象的属性或方法时,JavaScript会首先查找对象本身是否具有该属性或方法,如果没有,它会沿着原型链向上查找。


console.log(person1.hasOwnProperty('name')); // 输出: true,person1 自身具有 'name' 属性
console.log(person1.hasOwnProperty('greet')); // 输出: false,'greet' 在原型链上


### 4. **Object.create() 方法**
可以使用 `Object.create()` 方法创建一个新对象,并指定它的原型对象。这个方法常用于实现继承。


let personPrototype = {
  greet: function() {
    console.log('Hello, I am ' + this.name + '!');
  }
};
let person = Object.create(personPrototype);
person.name = 'John';
person.age = 30;
person.greet(); // 输出: Hello, I am John!


### 5. **继承与原型链**
通过设置构造函数的原型,可以实现对象之间的继承关系。下面是一个简单的例子:


function Animal(name) {
  this.name = name;
}
Animal.prototype.makeSound = function() {
  console.log('Some generic sound');
};
function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
  console.log('Woof! Woof!');
};
let myDog = new Dog('Buddy', 'Golden Retriever');
myDog.makeSound(); // 输出: Some generic sound
myDog.bark(); // 输出: Woof! Woof!


在这个例子中,`Dog` 继承了 `Animal` 的属性和方法。
通过了解和利用原型,你可以更好地组织和重用你的代码,实现面向对象编程的核心概念。

4.ES6--class

在ECMAScript 2015(ES6)及以后的版本中,JavaScript引入了类(Class)的概念,这是一种更简洁、更易读的语法糖,用于定义对象的构造函数和原型方法。让我们来看一下ES6中类的基本用法:
### 1. **类的定义**
使用 `class` 关键字定义类:


class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  greet() {
    console.log(`Hello, I am ${this.name}!`);
  }
}
let person = new Person('John', 30);
person.greet(); // 输出: Hello, I am John!


### 2. **构造函数与实例方法**
类中的 `constructor` 方法用于初始化对象的实例变量。其他方法则会被添加到类的原型中,成为实例的方法。
### 3. **实例化对象**
使用 `new` 关键字实例化对象:

### 4. **继承**
类可以通过 `extends` 关键字实现继承,子类可以调用父类的构造函数和方法:


class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // 调用父类的构造函数
    this.grade = grade;
  }
  study() {
    console.log(`${this.name} is studying.`);
  }
}
let student = new Student('Alice', 25, 'A');
student.greet(); // 输出: Hello, I am Alice!
student.study(); // 输出: Alice is studying.


### 5. **静态方法**
使用 `static` 关键字定义静态方法,这些方法属于类而不是实例:


class Calculator {
  static add(x, y) {
    return x + y;
  }
  static subtract(x, y) {
    return x - y;
  }
}
let result1 = Calculator.add(5, 3); // 8
let result2 = Calculator.subtract(8, 3); // 5


### 6. **Getter 和 Setter**
可以使用 `get` 和 `set` 关键字定义 getter 和 setter 方法:


class Circle {
  constructor(radius) {
    this._radius = radius; // 使用下划线表示私有属性
  }
  get radius() {
    return this._radius;
  }
  set radius(value) {
    if (value <= 0) {
      console.error('Radius must be a positive number.');
      return;
    }
    this._radius = value;
  }
  get area() {
    return Math.PI * this._radius ** 2;
  }
}
let circle = new Circle(5);
console.log(circle.radius); // 输出: 5
circle.radius = 8;
console.log(circle.area); // 输出: 201.06192982974676


这些是ES6中类的基本用法,它们简化了对象的创建和继承,并提供了更清晰的语法。

5.面向对象继承

面向对象编程中的继承是一种重要的概念,它允许一个对象获取另一个对象的属性和方法。在面向对象编程中,继承通常分为两种类型:类继承和原型继承。
### 类继承
在类继承中,一个类可以派生出另一个类,派生类可以继承基类的属性和方法。


class Animal {
  constructor(name) {
    this.name = name;
  }
  makeSound() {
    console.log('Some generic sound');
  }
}
class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 调用基类(父类)的构造函数
    this.breed = breed;
  }
  bark() {
    console.log('Woof! Woof!');
  }
}
let myDog = new Dog('Buddy', 'Golden Retriever');
myDog.makeSound(); // 输出: Some generic sound
myDog.bark(); // 输出: Woof! Woof!


在这个例子中,`Dog` 类继承了 `Animal` 类的属性和方法,并添加了自己的 `bark` 方法。
### 原型继承
在原型继承中,一个对象可以直接继承另一个对象作为其原型,从而共享原型对象的属性和方法。


let animal = {
  makeSound: function() {
    console.log('Some generic sound');
  }
};
let dog = Object.create(animal);
dog.bark = function() {
  console.log('Woof! Woof!');
};
dog.makeSound(); // 输出: Some generic sound
dog.bark(); // 输出: Woof! Woof!


在这个例子中,`dog` 对象直接继承了 `animal` 对象作为其原型,并添加了自己的 `bark` 方法。
类继承和原型继承都是面向对象编程中用于实现代码重用和组织的重要手段。选择合适的继承方式取决于项目的需求和设计。

29.AJAX

AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,通过后台与服务器进行数据交换的技术。它允许在不刷新整个页面的情况下异步地更新页面的部分内容。尽管名称中包含 "XML",实际上 AJAX 可以与多种数据格式一起使用,包括 JSON、HTML、纯文本等。
主要特点和优势包括:
1. **异步通信:** AJAX 使用异步通信机制,允许在不阻塞用户界面的情况下向服务器发送请求和接收响应。


2. **部分页面更新:** 可以在不刷新整个页面的情况下更新页面的一部分,提高用户体验并减少服务器负载。


3. **数据格式的灵活性:** 虽然最初的名字中包含 "XML",但实际上 AJAX 可以与多种数据格式一起使用,如 JSON、HTML、纯文本等。


4. **减少带宽使用:** 由于只更新页面的一部分,相对于传统同步请求,AJAX 可以减少对带宽的需求。


5. **交互性增强:** 通过 AJAX,可以实现更多的交互性,例如实时搜索、动态加载内容等。


使用 AJAX 的基本步骤包括:
1. **创建 XMLHttpRequest 对象:** XMLHttpRequest 对象用于与服务器进行异步通信。
2. **创建回调函数:** 在收到服务器响应时,执行回调函数来处理响应数据。
3. **打开和发送请求:** 使用 XMLHttpRequest 对象打开到服务器的连接,并发送请求。
4. **处理服务器响应:** 在回调函数中处理从服务器返回的数据,并更新页面的相应部分。
在现代的 Web 开发中,除了原生的 XMLHttpRequest,还可以使用现代的 Fetch API 或各种 JavaScript 框架(如 jQuery、axios)来简化 AJAX 请求的处理。例如,使用 Fetch API,一个简单的 AJAX 请求可能如下所示:


fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    // 处理从服务器获取的数据
    console.log(data);
  })
  .catch(error => {
    // 处理请求错误
    console.error('Error:', error);
  });


总的来说,AJAX 是一种强大的技术,使得 Web 应用能够更加动态和交互,提高用户体验。

客户端给服务端发送消息的工具,以及接受响应的工具

是默认的异步执行机制

优势

  1. 不需要插件的支持 ,原生(js)使用

  2. 用户体验好(不需要刷新页面)

  3. 减轻服务端和宽带的负担

  4. 缺点:搜索引擎的支持度不够,因为数据不在页面上,搜索引擎搜索不到

http状态码

1xx系列:信息性状态码

1xx系列的状态码表示服务器已经接收到请求并正在处理,但需要进一步的操作才能完成请求。

100 Continue:表示服务器已经接收到请求的头部,并且客户端应该继续发送请求的主体部分。

101 Switching Protocols:表示服务器已经理解了客户端的请求,并且将切换到不同的协议来完成请求。

2xx系列:成功状态码

2xx系列的状态码表示请求已经成功被服务器接收、理解和处理。

200 OK:表示请求已成功,服务器正常处理并返回请求的资源。

201 Created:表示请求已成功,并且服务器创建了新的资源。

202 Accepted:表示服务器已接受请求,但尚未处理完成。

204 No Content:表示请求已成功,但服务器没有返回任何内容。

3xx系列:重定向状态码

3xx系列的状态码表示客户端需要进行进一步的操作才能完成请求。

301 Moved Permanently:表示请求的资源已永久移动到新的URL。

302 Found:表示请求的资源已临时移动到新的URL。

304 Not Modified:表示请求的资源未被修改,可以直接使用缓存的版本。

4xx系列:客户端错误状态码

4xx系列的状态码表示客户端发起的请求有错误或无法完成。

400 Bad Request:表示客户端发送的请求有语法错误。

401 Unauthorized:表示请求需要用户进行身份验证。

403 Forbidden:表示服务器拒绝请求,没有权限访问。

404 Not Found:表示请求的资源不存在。

5xx系列:服务器错误状态码

5xx系列的状态码表示服务器在处理请求时发生了错误。

500 Internal Server Error:表示服务器内部发生了错误。

502 Bad Gateway:表示服务器作为网关或代理,从上游服务器接收到无效的响应。

503 Service Unavailable:表示服务器当前无法处理请求,一般是由于过载或维护导致。

2.创建原生xhr请求

       //  第一步 创建   XHR  new  XMLHttpRequest()
 
  
        // ajax===async  javascript and  xml (闭合标签)

        // JSON.parse()  //字符串类型转为字典
        
        let   xhr=new XMLHttpRequest()  //创建实例化对象
  
        // 第二步 配置  open(请求方式,请求地址,是否异步)

         xhr.open('GET',url,true)  是否异步   默认是false
         
          //  第三步 发送请求
          xhr.send()
        // 第四步 接受数据,注册一个事件  

        xhr.onreadystatechange=function(){
            if(xhr.status===200 && xhr.readyState===4){ 
              //状态码200 与运行状态到4都满足
              console.log(xhr.responseText)     //获取数据打印              
            }else if(xhr.readyState===4 && xhr.status===404)            {       
                           console.error(xhr.status)
            }
        }

ajax状态码-xhr.readyState

用来表示一个ajax请求的全部过程的一个状态

readyState===0 表示未初始化完成,open没有执行完毕

readyState===1 表示配置信息已经完成,也就是open执行完毕了

readyState===2 表示 send 已经执行完毕

readyState===3 表示表示正在解析响应内容

readyState===4 表示内容解析完毕,可以使用

状态码为200~299

一个ajax对象中有一个成员是xhr.status

记录的是本次请求的http状态码

在第四步接收数据需要注册事件分别是onreadystatechange与onload

1.onreadystatechange只打印其状态为2,状态为3,状态为4。

2.进入onload之后,只出现了状态码4。也就是说,只有处于状态码4,请求已完成,响应已就绪的情况下,才会进入onload。只要进入onload请求中,一定是已经到4这个状态了

在第四步接收数据需要注册事件分别是onreadystatechange与onload

1.onreadystatechange只打印其状态为2,状态为3,状态为4。

2.进入onload之后,只出现了状态码4。也就是说,只有处于状态码4,请求已完成,响应已就绪的情况下,才会进入onload。只要进入onload请求中,一定是已经到4这个状态了

请求方式

get 偏向获取数据

post 偏向提交数据

put偏向更新数据

delete偏向删除信息

patch 部分数据修改

header 服务器头信息

options服务器设备信息

connnect获取请求方式

案例:

get请求

var  xhr=XMLRequestHttp()
xhr.open('get','地址',true)
xhr.onload=function(){
   if(xhr.status===200){
       console.log(JSON.parse(xhr.responseText))
   }
}
xhr.send()发送请求

post请求

var  xhr=XMLRequestHttp()  创建对象
xhr.open('post','地址',tue)
xhr.onload=function(){
     if(xhr.status===200){
        console.log(JSON.parse(xhr.responseText))
     }
     
      Content-Type','application/json
     
     请求头的设置
     xhr.setReuqestHeader('Content-Type':'application/x-www-form-urlencoded')
 
}
//这是发送给后端的内容
xhr.send('name=zjq&age=18')

30.promise

Promise 是 JavaScript 中处理异步操作的一种机制,它可以更优雅和可读地处理异步代码,避免了回调地狱(Callback Hell)。Promise 对象有三个状态:pending(进行中)、fulfilled(已成功)、rejected(已失败),一旦状态改变,就会触发相应的处理函数。
### 创建 Promise


const myPromise = new Promise((resolve, reject) => {
  // 异步操作,例如从服务器获取数据
  // 操作成功时调用 resolve,并传递结果
  resolve('成功的数据');
  // 操作失败时调用 reject,并传递错误信息
  // reject('失败的原因');
});


### 处理 Promise 状态


myPromise.then(
  // 处理成功状态
  (result) => {
    console.log('成功:', result);
  },
  // 处理失败状态
  (error) => {
    console.error('失败:', error);
  }
);


### Promise 链式调用


myPromise
  .then((result) => {
    // 处理第一次成功状态
    console.log('第一次成功:', result);
    // 返回一个新的 Promise 对象
    return '新的数据';
  })
  .then((result) => {
    // 处理第二次成功状态
    console.log('第二次成功:', result);
  })
  .catch((error) => {
    // 处理任何一个失败状态
    console.error('失败:', error);
  })
  .finally(() => {
    // 不论状态如何,都会执行的代码块
    console.log('不论成功或失败,都会执行的代码块');
  });


### Promise.all


const promise1 = Promise.resolve('Promise 1');
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Promise 2'), 2000));
const promise3 = fetch('https://api.example.com/data');
Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log('全部完成:', results);
  })
  .catch((error) => {
    console.error('其中一个失败:', error);
  });


### Promise.race


const promise1 = new Promise((resolve) => setTimeout(() => resolve('Promise 1'), 1000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Promise 2'), 2000));
Promise.race([promise1, promise2])
  .then((result) => {
    console.log('第一个完成的 Promise:', result);
  })
  .catch((error) => {
    console.error('其中一个失败:', error);
  });


Promise 提供了一种更结构化、可维护的方式来处理异步操作,使得代码更清晰。在实际开发中,它广泛用于处理网络请求、文件读写、定时任务等异步场景。

31.async和await用法

`async` 和 `await` 是用于处理 JavaScript 中异步操作的语法糖,它们让异步代码更易于理解和编写。下面是它们的详细用法:
### `async` 函数
`async` 函数是返回一个 Promise 对象的函数。在函数内部,使用 `await` 关键字可以暂停函数的执行,等待 `Promise` 解决,并返回 `Promise` 解决的值。这样可以避免使用传统的回调函数和处理 Promise 链的复杂性。


async function fetchData() {
  // 使用 await 暂停执行,等待 Promise 解决
  let result = await someAsyncOperation();
  return result; // 返回 Promise 解决的值
}


### `await` 关键字
`await` 只能在 `async` 函数内部使用。它等待一个 Promise 解决,并返回该 Promise 解决的值。如果 `await` 后面的表达式不是 Promise,它将被转换为已解决的 Promise。


async function example() {
  let result = await someAsyncOperation();
  console.log(result); // 输出 Promise 解决的值
}


### 错误处理
在 `async` 函数中,可以使用 `try...catch` 块来捕获 `await` 表达式的错误。


async function fetchData() {
  try {
    let result = await someAsyncOperation();
    return result;
  } catch (error) {
    console.error(error);
    // 进行错误处理
  }
}


### 多个并行的异步操作
`await` 关键字也可以用于多个并行的异步操作,以提高性能。


async function parallelOperations() {
  let [result1, result2] = await Promise.all([asyncOperation1(), asyncOperation2()]);
  console.log(result1, result2);
}


### 注意事项
- `await` 只能在 `async` 函数内部使用。
- `await` 暂停整个 `async` 函数的执行,直到 `Promise` 解决或拒绝。
- `async` 函数始终返回一个 Promise,可以是已解决的 Promise(如果函数返回值为非 Promise,则自动包装为已解决的 Promise),也可以是等待异步操作结果的 Promise。
`async` 和 `await` 简化了异步代码的书写,并改善了代码的可读性,但需要注意避免过度使用,以免影响代码的执行性能。

32.fetch

`fetch` 是一种用于发起网络请求的现代化的 JavaScript API。它提供了一种更强大、更灵活的替代方案,取代了过去常用的基于回调的 `XMLHttpRequest`。
### 基本用法(默认的)


fetch('https://api.example.com/data')
  .then(response => {
    // 处理响应
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json(); // 返回一个 Promise,解析为 JSON 数据
  })
  .then(data => {
    // 处理解析后的数据
    console.log(data);
  })
  .catch(error => {
    // 处理错误
    console.error('Fetch error:', error);
  });


### 请求配置
`fetch` 可以接受第二个参数,用于配置请求的各种选项,例如请求方法、头部信息、请求体等。


fetch('https://api.example.com/data', {
  method: 'POST', // 请求方法
  headers: {
    'Content-Type': 'application/json' // 请求头部
  },
  body: JSON.stringify({ key: 'value' }) // 请求体
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Fetch error:', error));


### 处理跨域请求
在默认情况下,浏览器会阻止跨域请求。可以使用 `mode` 选项来配置跨域请求的处理方式。


fetch('https://api.example.com/data', {
  mode: 'cors' // 允许跨域请求
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Fetch error:', error));


### 取消请求
`fetch` 返回一个 Promise,可以使用 `AbortController` 来取消请求。


const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Request was aborted');
    } else {
      console.error('Fetch error:', error);
    }
  });
// 取消请求
controller.abort();


`fetch` 的优点包括语法简洁、返回 Promise、更灵活的配置选项等。但需要注意的是,它不会自动发送或接收 cookies,需要手动配置 `credentials` 选项。

1.post请求

如果你想使用 `fetch` 发起 POST 请求,可以通过在请求配置中设置 `method` 为 `'POST'` 并提供 `body` 来实现。以下是一个基本的示例:


fetch('https://api.example.com/data', {
  method: 'POST', // 请求方法为 POST
  headers: {
    'Content-Type': 'application/json' // 设置请求头部为 JSON 格式
  },
  body: JSON.stringify({ key: 'value' }) // 提供请求体数据
})
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('Fetch error:', error);
  });


在这个示例中,`method` 被设置为 `'POST'`,并且通过 `headers` 设置了请求头部,`body` 包含了要发送的数据,使用 `JSON.stringify` 将 JavaScript 对象转换为 JSON 字符串。
记得根据实际情况修改请求的 URL、请求头部和请求体。

2.put请求

要使用 `fetch` 发起 PUT 请求,你可以通过设置请求配置中的 `method` 为 `'PUT'` 并提供 `body` 来实现。以下是一个简单的示例:


fetch('https://api.example.com/data/123', {
  method: 'PUT', // 请求方法为 PUT
  headers: {
    'Content-Type': 'application/json' // 设置请求头部为 JSON 格式
  },
  body: JSON.stringify({ updatedKey: 'updatedValue' }) // 提供要更新的数据
})
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => {
    console.log('Update successful:', data);
  })
  .catch(error => {
    console.error('Fetch error:', error);
  });


在这个示例中,`method` 被设置为 `'PUT'`,并且通过 `headers` 设置了请求头部,`body` 包含了要发送的更新数据,使用 `JSON.stringify` 将 JavaScript 对象转换为 JSON 字符串。
请确保根据实际情况修改请求的 URL、请求头部和请求体中的数据内容。

注意:

常见的请求方式都可以使用类似于post这样请求方式请求数据,默认的fetch请求是get请求

33.cookie

Cookie 是存储在用户计算机上的小型文本文件,由网站通过用户的浏览器存储。它用于在用户和网站之间保持状态信息,以及跟踪用户的活动。Cookie 是 HTTP 协议的一部分,被广泛用于 Web 开发中。
### 创建和设置 Cookie
服务器通过 HTTP 头部的 Set-Cookie 字段向客户端发送 Cookie。以下是一个基本的 Set-Cookie 头部的示例:


Set-Cookie: name=value; expires=Sat, 01 Jan 2022 00:00:00 GMT; path=/; domain=example.com; secure; httponly
- `name=value`: Cookie 的键值对,存储数据的主体。
- `expires`: Cookie 的过期时间,超过该时间后 Cookie 将被删除。
- `path`: 指定 Cookie 的有效路径,决定了哪些路径下的请求会发送 Cookie。
- `domain`: 指定 Cookie 的有效域,决定了哪些域下的请求会发送 Cookie。
- `secure`: 表示该 Cookie 只能通过 HTTPS 连接传输。
- `httponly`: 表示该 Cookie 不能通过 JavaScript 访问,有助于防止跨站脚本攻击(XSS)。


### 读取和使用 Cookie
浏览器会自动将 Cookie 存储在一个名为 `document.cookie` 的对象中,可以通过该对象读取和设置 Cookie。以下是一个基本的读取和使用 Cookie 的示例:


// 读取所有 Cookie
const allCookies = document.cookie;
// 读取特定 Cookie
const specificCookie = document.cookie.split('; ').find(cookie => cookie.startsWith('name='));
// 设置 Cookie
document.cookie = 'newCookie=newValue; expires=Sat, 01 Jan 2023 00:00:00 GMT; path=/; domain=example.com; secure; httponly';


### Cookie 的限制和注意事项
- 每个域名下的 Cookie 数量和大小都是有限制的,超过限制可能导致一些问题。
- Cookie 是明文存储在用户设备上的,因此不应该存储敏感信息。
- 使用 Secure 标志可以确保 Cookie 只通过加密的 HTTPS 连接传输,增强安全性。
- 使用 HttpOnly 标志可以防止通过 JavaScript 访问 Cookie,提高安全性。
Cookie 是一种方便的机制,用于在客户端和服务器之间保持状态。然而,由于安全和隐私的考虑,现代应用更倾向于使用其他存储方式,如 Web Storage 或者更安全的 HTTP-only Cookies。

34.jsonp

`JSONP`(JSON with Padding)是一种用于解决跨域数据访问的技术。由于浏览器的同源策略(Same-Origin Policy)限制,通常情况下,一个网页只能请求同源(相同协议、域名、端口)的数据,无法直接访问其他域下的数据。而 JSONP 则是通过动态创建 `<script>` 标签的方式来实现跨域请求的。
### JSONP 的基本原理
1. **动态创建 `<script>` 标签:** 客户端通过在页面中动态创建一个 `<script>` 标签,将请求发送到希望访问数据的服务器。
2. **回调函数:** 在请求中指定一个回调函数的名称,该回调函数在服务器端返回数据时会被调用。
3. **服务器返回数据:** 服务器接收到请求后,将数据作为参数传递给指定的回调函数,返回的数据被包裹在函数调用中。
4. **客户端处理数据:** 客户端定义的回调函数会被调用,从而在页面中处理返回的数据。
### JSONP 的使用示例
以下是一个简单的 JSONP 请求的示例:
 


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JSONP Example</title>
</head>
<body>
  <script>
    // 定义回调函数
    function handleData(data) {
      console.log('Data received:', data);
    }
    // 创建动态 script 标签
    const script = document.createElement('script');
    // 设置 script 标签的 src 属性,包括回调函数名称和数据源
    script.src = 'https://api.example.com/data?callback=handleData';
    // 将 script 标签添加到页面中
    document.body.appendChild(script);
  </script>
</body>
</html>

35.闭包

闭包是JavaScript中一个重要且强大的概念。它形成于函数嵌套函数的情境中,允许内部函数访问外部函数作用域中的变量。闭包可以捕获并保持其诞生环境的状态,即使该环境已经不存在了。
举个例子:


function outerFunction() {
  let outerVar = 'I am from the outer function';
  
  function innerFunction() {
    console.log(outerVar);
  }
  return innerFunction;
}
let closure = outerFunction();
closure(); // 输出: I am from the outer function


在这个例子中,`innerFunction` 是一个闭包,它可以访问外部函数 `outerFunction` 中声明的 `outerVar` 变量,即使 `outerFunction` 已经执行完毕并返回了。
闭包的特性使其非常有用,可以用于创建私有变量、模块化开发、延迟执行等。但需要注意,过度或不正确地使用闭包可能导致内存泄漏,因为闭包会持有外部函数的作用域链。因此,在使用闭包时,需要注意内存管理和对作用域链的了解,以免出现意外的内存消耗问题。

36.异常捕获

在JavaScript中,异常捕获是通过使用 `try...catch` 语句实现的。这个结构允许你尝试执行一些可能引发异常的代码,然后在出现异常时捕获并处理它。
以下是一个基本的 `try...catch` 结构的示例:


try {
  // 可能引发异常的代码
  throw new Error("这是一个示例异常");
} catch (error) {
  // 异常被捕获并在这里处理
  console.error("捕获到异常:", error.message);
} finally {
  // 不管是否发生异常,这里的代码都会执行
  console.log("这里总是会执行的代码");
}


解释一下:
- `try` 块中包含可能引发异常的代码。
- 如果在 `try` 块中的代码引发了异常,控制流将跳到 `catch` 块,其中的 `error` 参数包含有关异常的信息。
- `finally` 块中的代码总是会执行,无论是否发生异常。它通常用于确保资源得到正确释放,即使发生异常也能执行清理工作。
你也可以使用多个 `catch` 块来捕获不同类型的异常:


try {
  // 可能引发异常的代码
  throw new TypeError("这是一个类型错误");
} catch (typeError) {
  console.error("捕获到类型错误:", typeError.message);
} catch (error) {
  console.error("捕获到其他异常:", error.message);
} finally {
  console.log("这里总是会执行的代码");
}


请注意,异常捕获应该谨慎使用,避免滥用。在实际开发中,最好只捕获你能够处理的异常,而将不可预料的异常交给全局错误处理机制处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值