JS基础

JS基础

_

一,介绍

1.1 基础知识

  • JavaScript 是什么?

    • 是一种运行在客户端(浏览器)的编程语言,实现人机交互效果。
  • JavaScript 的作用

    • 网页特效(监听用户的一些行为让网页作出对应的反馈)
    • 表单验证(针对表单数据的合法性进行判断)
    • 数据交互(获取后台的数据,渲染到前端)
    • 服务端编程(node.js)

2953321-20240908191656420-247499334.png

  • JavaScript 的组成

    • ECMAScript:
      • 规定了js基础语法核心知识,例如变量,分支语句,循环,对象等。
    • Web APIs
      • DOM:操作文档,比如对页面元素进行移动,大小,添加删除等操作。
      • BOM:操作浏览器,比如页面弹窗,检测窗口宽度,存储数据到浏览器等。

2953321-20240908192039938-1290063988.png

1.2 JS书写位置

  1. 内部 JavaScript

    直接写在 html 文件里,用 script 标签包住
    规范:script 标签写在</body>上面

  2. 外部 JavaScript

    代码写在以.js 结尾的文件里面

    语法:通过 scrippt 标签,将 js 引入 html 页面中

    <body>
        <script src="my.js"></script>
    </body>
    

    script 标签中间无需写代码,否则会被忽略!

    外部 lavascript 会使代码更加有序,更易于复用,且没有了脚本的混合,HTML 也会更加易读,因此这是个好的习惯。

  3. 内联 JavaScript

    代码写在标签内部

    语法:

    <body>
        <button onclick="alert('内联js')">
            按钮
        </button>
    </body>
    

    只做了解,实际代码不这么写

1.3 JS注释和结束符

  • 单行注释

    //注释,快捷键是ctrl+/
    
  • 多行注释

    /*
    	多行注释,快捷键是shift+alt+a
    */
    
  • 结束符

    • 作用:使用英文的;代表语句结束
    • 实际情况:实际开发中,可写可不写,浏览器可以自动推断语句结束位置

2953321-20240908192900676-1884955834.png

1.4 输入输出语法

  • 输出语法

    • 语法 1

      document.write('要输出的内容')
      document.write('<h1>要输出的内容</h1>')
      

      作用:向 body 内输出内容

      注意:如果输出的内容写的是标签,也会被解析成网页元素

    • 语法 2

      alert('要输出的内容')
      

      作用:页面弹出警告对话框

    • 语法 3

      console.log('控制台打印')
      

      作用:控制台输出语法,我们 f12 的时候查看控制台调试用的

  • 输入语法

    • 语法

      prompt('请输入你的name')
      

      作用:显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

      效果:

2953321-20240908193345648-786467897.png

JavaScript 代码执行顺序

  • 按HTML文档流顺序执行JavaScript代码
  • alert()prompt()它们会跳过页面渲染先被执行

二,变量

在 JavaScript 中,变量是用于存储数据的“容器”。可以通过varletconst来声明变量,这三者有不同的作用域和行为

2. 1 var 声明的变量

  • 作用域: var声明的变量有函数作用域。它在声明所在的函数内有效,如果在函数外声明,它就会是全局变量。
  • 变量提升(Hoisting): var声明的变量会提升到函数或全局作用域的顶部,但赋值保持原位。即使在声明之前使用,JavaScript不会报错,只是值为undefined
  • 重复声明: 可以多次用var声明同一个变量。
console.log(x);  // undefined
var x = 10;
console.log(x);  // 10

2.2 let 声明的变量

  • 作用域: let具有块作用域,只在声明所在的块(例如{}内)有效。常用于局部变量。
  • 变量提升: 虽然let也会提升,但在其声明之前不能访问变量,会抛出ReferenceError。这种行为叫暂时性死区(Temporal Dead Zone, TDZ)。
  • 重复声明: 在同一作用域内,不能重复声明同一个变量。
// console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 20;
console.log(y);  // 20

2.3 const 声明的变量

  • 作用域: const也具有块作用域,与let相同。
  • 常量: const用于声明常量,声明时必须赋值,之后不能再被重新赋值。不过,如果const声明的是一个对象或数组,虽然不能改变对这个对象的引用,但可以修改对象的属性或数组的元素。
  • 变量提升: constlet相同,也有暂时性死区。
  • 重复声明: 在同一作用域内,不能重复声明同一个变量。
const z = 30;
// z = 40; // TypeError: Assignment to constant variable

2.4 小结

  • 使用var在现代JavaScript开发中逐渐减少,建议使用letconst
  • let适用于需要改变值的变量,const则适用于声明常量或不会重新赋值的变量。

三,数据类型

JS 数据类型分为两大类:

  • 基本数据类型
    • number数字型
    • string字符串型
    • boolean布尔型
    • undefined未定义型
    • null空类型
  • 引用数据类型
    • object对象

3.1 基本数据类型

3.1.1 number数字型

JavaScript 中的正数、负数、小数等 统一称为 数字类型。

let age = 18 //整数
let price = 88.99 //小数

注意:

  • JS是弱数据类型,变量到底数据哪种类型,只有赋值后我们才能确定

3.1.2 string字符串型

通过单引号'',双引号" ",反引号,包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。

let uname = '小明'	//使用单引号
let gender = "男"	//使用双引号
let str= '' //这种情况叫空字符串

注意点:

  • 无论单引号还是双引号必须成对使用
  • 单引号/双引号可以互相嵌套,但是不以自已嵌套自已(口诀 :外双内单,或者外单内双 )
  • 必要时可以使用转义符\,输出单引号或双引号

字符串拼接:

  • 场景:+ 运算符可以实现字符串的拼接
  • 口诀:数字相加,字符相连

模板字符串

  • 使用场景:拼接字符串和变量

  • 用法

    • 使用反引号
    • 内容拼接变量时,用 ${}包住变量
    document.write('使用模板字符串之前的写法'+num+'测试')
    document.write(`使用模板字符串之后的写法${num}测试`)
    

3.1.3 boolean布尔型

表示肯定或否定时在计算机中对应的是布尔类型数据

它有两个固定的值 true 和 false,表示肯定的数据用 true(真),表示否定的数据用 false(假)。

let isTrue=true
console.log(isTrue)

3.1.4 undefined未定义型

未定义类型是比较特殊的数据类型,只有一个取值undefined

出现 undefined 的情况

  • 只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined。

开发中使用场景:

  • 我们开发中经常声明一个变量,等待传送过来的数据,
    如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来。

3.1.5 null空类型

JavaScript 中的 null 仅仅是一个代表无,空值未知的特殊值。

let obj=null

null 和 undefined 的区别

  • undefined 表示没有赋值
  • null 表示赋值了,但是内容为空

null 开发中的使用场景:

  • 将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null

3.2 检测数据类型

通过 typeof 关键字检测数据类型

  • typeof 运算符可以返回被检测的数据类型。它支持两种语法形式:

    typeof x	//作为运算符
    typeof(x)	//作为函数形式
    

    换言之,有括号和没有括号,得到的结果是一样的,所以我们直接使用运算符的写法。

3.3 类型转换

JavaScript 是弱数据类型,JavaScript 也不知道变量到底属于那种数据类型,只有赋值了才清楚

坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。

3.3.1 隐式转换

某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。

规则:

  • +号两边只要有一个是字符串,都会把另外一个转成字符串
  • 除了+以外的算术运算符 比如-*/等都会把数据转成数字类型

缺点

  • 转换类型不明确,需要经验才能总结

技巧:

  • +号作为正号解析可以转换成数字型

    console.log(+'123')//数字型
    
  • 任何数据和字符串相加结果都是字符串

  • 减法 -,会导致空字符串 "" 转换为 0

  • null 结果数字转换后会变成 0

  • undefined 结果数字转换会变成 NaN

3.3.2 显示转换

编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。

为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。

写法

  • Number(数据)
    • 转化为数字类型
    • 如果字符串内容里有非数字,转换失败时结果为 NaN(NotaNumber)即不是一个数字
    • NaN也是number类型的数据,代表非数字
  • parseInt(数据)
    • 只保留整数
  • parseFloat(数据)
    • 可保留小数

四,运算符

4.1 算数运算符

数字可以有很多操作,比如,乘法 *、除法 /、加法 +、减法 - 等等,所以经常和算术运算符一起。

数学运算符也叫算术运算符,主要包括加、减、乘、除、取余 (求模)。

  • +:求和
  • -:求差
  • *:求积
  • /:求商
  • %:取模(取余)

运算符优先级:同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。JavaScript 中 优先级越高越先被执行,优先级相同时以书从左向右执行

  • 乘、除、取余优先级相同
  • 加、减优先级相同
  • 乘、除、取余优先级大于加、减
  • 使用()可以提升优先级
  • 总结:先乘除后加减,有括号先算括号里面的

4.2 赋值运算符

赋值运算符:对变量进行赋值的运算符

  • =:将等号右边的值赋予给左边,要求左边必须是一个容器

  • +=

    let nun=1
    num +=1 //等价于num = num +1
    
  • -=

    let nun=1
    num -=1 //等价于num = num -1
    
  • *=

    let nun=1
    num *=1 //等价于num = num*1
    
  • /=

    let nun=1
    num /=1 //等价于num = num/1
    
  • %=

    let nun=1
    num %=1 //等价于num = num%1
    

4.3 自增运算符

  • 自增
    • 符号:++
    • 作用:让变量值+1
  • 自减
    • 符号:--
    • 作用:让变量值-1
let num=1
num++
num--

需要注意 ++ 和 -- 的位置不同效果也不同

  • num++++num是不一样的
  • a-num++代表的是先运算a-num然后再给num+1
  • a+ ++num代表的是先运算num+1然后计算a-num

4.4 比较运算符

比较运算符:

  • >:大于
  • <:小于
  • >=:大于等于
  • <=:小于等于
  • ==值等于
  • ===类型和值等相等(开发中更推荐使用这个)
  • !=:值不等于
  • !==:类型和值是否都不相等

比较结果为 boolean 类型,只会得到 true 或 false

坑点:

  • 字符串比较,是比较字符对应的 ASCII 码

    • 从左往右依次比较

    • 如果第一位一样再比较第二位,以此类推

    • 比较的少,了解即可

  • NaN 不等于任何值,包括它本身。

  • 尽量不要比较小数,因为小数存在精度问题

  • 不同类型之间比较会发生隐式转换

    console.log(2 == '2')//结果为true,因为比较运算符存在隐式类型转换,会把'2'变成2,因为==值判断值
    console.log(2 === '2‘)//结果为false,因为===同时比较值和类型
    

4.5 逻辑运算符

符号名称特点
&&逻辑与两边都为true结果才为true
||逻辑或有一个true结过就是true
!逻辑非true变false,false变true

4.6 运算符优先级

优先级运算符顺序
1(最高)小括号()
2一元运算符++ -- !
3算数运算符先* / %后+ -
4关系运算符> >= < <=
5相等运算符== != === !==
6逻辑运算符先&&后||
7赋值运算符=
8逗号运算符,

别管这么多,知道数学加减乘除顺序,知道 () 优先级最高,知道 && 大于 || 就好了

五,流程控制语句

5.1 表达式

表达式是可以被求值的代码,JavaScript 引擎会将其计算出一个结果。

例如:

num=3+4

2953321-20240909184643869-1952147779.png

5.2 分支语句

分支语句可以让我们有选择性的执行想要的代码。

5.2.1 if分支语句

  • 单分支

    if(条件){
        //满足条件执行的代码
    }
    
  • 双分支

    if(条件){
        //满足条件执行的代码
    }else{
        //不满足条件执行的代码
    }
    
  • 多分支

    if(条件){
        //满足条件执行的代码
    }else if(条件2){
        //满足条件执行的代码
    }else{
        //不满足条件执行的代码
    }
    

注意点:

  • 括号内的条件为 true 时,进入大括号里执行代码

  • 小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型

  • 如果大括号只有一个语句,大括号可以省略,但是,不提倡这么做

5.2.2 三元运算符

语法:

条件 ? 满足条件执行的语句 : 不满足条件执行的语句

5.2.3 switch语句

语法:

switch(表达式){
    case 值1:
        代码1
        break
    case 值2:
        代码2
        break
    case 值3:
        代码3
        break
    default:
        默认代码
        break
}

注意点:

  • switch case语句用于等值判断,不适合于区间判断
  • switch case一般需要配合break关键字使用 没有break会造成case穿透

5.3 循环语句

循环:重复执行一些操作,

5.3.1 while循环

语法:

while(循环条件){
    //要重复执行的代码(循环体)
}
  • 跟if语句很像,都要满足小括号里的条件为true才会进入循环体 执行代码
  • while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到
    小括号判断条件,直到括号内条件不满足,即跳出

while 循环三要素:循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。所以,while 循环需要具备三要素:

  1. 变量起始值
  2. 循环终止条件(没有终止条件,循环会一直执行,造成死循环)
  3. 变量变化量(用自增或者自减)

举例:

let i=1
while(i <=3 ){
    console.log(`次数${i}`)
    i++
}

5.3.2 循环关键字

循环结束关键字:

  • break:退出循环
  • continue:结束本次循环,继续下次循环

举例:

let i=1
while(true){
    if(i == 3){
        break//结束循环
    }
    console.log(`次数${i}`)
    i++
}
let j=1
while(true){
    if(j == 3){
        continue//结束本次循环执行,继续下次循环
    }
    console.log(`次数${i}`)
    i++
}

5.3.3 for循环

  • 作用:重复执行代码

  • 好处:把声明起始值、循环条件、变化值写到一起,让人一目了然,它是最常使用的循环形式

  • 语法:

    for(变量起始值;终止条件;变量变化量){
        //循环体
    }
    for(let i=1;i<=3;i++){
         console.log(`次数${i}`)
    }
    

5.3.4 循环嵌套

循环嵌套:一个循环里面再嵌套一个循环,一般用在 for 循环里面。

for(外部声明记录循环次数的变量;循环条件;变化值){
    for(内部声明记录循环次数的变量;循环条件;变化值){
    	//循环体
	}	
}
  • 不只是可for循环嵌套,for也可以和while相互嵌套,无所谓的,看具体实现。
  • break和continue也可以用到for循环里面的,结束的是当前这个循环,具体看在哪个循环体里面。

六,Array数组

JavaScript 中的数组是用于存储多个值的列表。数组是非常灵活的,可以包含各种类型的数据,并且有许多内置方法来操作数组。本文将介绍 JavaScript 数组的常见操作,包括创建数组、修改数组、遍历数组、排序、过滤、映射等操作。


6.1 创建数组

数组可以通过多种方式创建:

  • 空数组

    let arr1 = [];
    let arr2 = new Array()
    
  • 带有初始值的数组

    let fruits = ['apple', 'banana', 'orange'];
    let arr2 = new Array('apple', 'banana', 'orange')
    let numbers = [1, 2, 3, 4, 5];
    

数组中的元素可以是任何数据类型,甚至可以是对象或其他数组。


6.2 访问数组元素

使用索引访问数组元素,索引从 0 开始:

let fruits = ['apple', 'banana', 'orange'];
console.log(fruits[0]); // 输出 'apple'
console.log(fruits[2]); // 输出 'orange'

6.3 修改数组元素

数组的元素是可修改的,可以直接通过索引修改:

let fruits = ['apple', 'banana', 'orange'];
fruits[1] = 'grape';
console.log(fruits); // ['apple', 'grape', 'orange']

6.4 数组长度

可以使用 .length 属性获取数组的长度:

let fruits = ['apple', 'banana', 'orange'];
console.log(fruits.length); // 3

6.5 数组方法

6.5.1 添加元素

  • push():在数组末尾添加元素

    let fruits = ['apple', 'banana'];
    fruits.push('orange');
    console.log(fruits); // ['apple', 'banana', 'orange']
    
  • unshift():在数组开头添加元素

    fruits.unshift('grape');
    console.log(fruits); // ['grape', 'apple', 'banana', 'orange']
    

6.5.2 删除元素

  • pop():从数组末尾删除元素

    fruits.pop();
    console.log(fruits); // ['grape', 'apple', 'banana']
    
  • shift():从数组开头删除元素

    fruits.shift();
    console.log(fruits); // ['apple', 'banana']
    

6.5.3 查找元素

  • indexOf():查找元素的索引

    let index = fruits.indexOf('banana');
    console.log(index); // 1
    
  • includes():检查数组是否包含某个元素

    let hasApple = fruits.includes('apple');
    console.log(hasApple); // true
    

6.5.4 遍历数组

  1. for 循环:最基本的方式

    let fruits = ['apple', 'banana', 'orange'];
    for (let i = 0; i < fruits.length; i++) {
        console.log(fruits[i]);
    }
    
  2. forEach():数组专用方法

    fruits.forEach(function(fruit) {
        console.log(fruit);
    });
    

6.6 数组排序

  • sort():按字母顺序对数组进行排序

    let fruits = ['apple', 'banana', 'orange'];
    fruits.sort();
    console.log(fruits); // ['apple', 'banana', 'orange']
    
  • 对数字进行排序时,sort() 会将数字当作字符串处理,需要提供比较函数:

    let numbers = [40, 1, 5, 200];
    numbers.sort((a, b) => a - b);
    console.log(numbers); // [1, 5, 40, 200]
    

6.7 数组映射

map():创建一个新数组,其中每个元素是原数组的操作结果:

let numbers = [1, 2, 3, 4];
let doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]

map 可以遍历数组处理数据,并返回新数组

const arr=['red','blue','green']
const newArr=arr.map(function(els,index){
    console.log(els)//数组元素
    console.log(index)//数组索引
    return els+'颜色'
})
console.log(newArr)//['red颜色','blue颜色','green颜色']

6.8 数组过滤

filter():根据条件筛选出符合条件的元素:

let numbers = [1, 2, 3, 4, 5];
let filtered = numbers.filter(num => num > 2);
console.log(filtered); // [3, 4, 5]

6.9 数组合并

concat():合并两个或多个数组:

let arr1 = [1, 2];
let arr2 = [3, 4];
let merged = arr1.concat(arr2);
console.log(merged); // [1, 2, 3, 4]

6.10 数组转字符串

join():将数组元素连接成一个字符串:

let fruits = ['apple', 'banana', 'orange'];
let result = fruits.join(', ');
console.log(result); // 'apple, banana, orange'

6.11 数组拆分和合并

  • splice():从数组中删除、添加或替换元素:

    let fruits = ['apple', 'banana', 'orange'];
    fruits.splice(1, 1); // 从索引 1 开始删除 1 个元素
    console.log(fruits); // ['apple', 'orange']
    
  • slice():截取数组的部分内容,返回一个新数组:

    let fruits = ['apple', 'banana', 'orange', 'grape'];
    let sliced = fruits.slice(1, 3); // 从索引 1 到 3 之间的元素
    console.log(sliced); // ['banana', 'orange']
    

七,函数

JavaScript 的函数是最基础且强大的编程构建块之一。它们是用来执行特定任务的可重用代码块。JavaScript 中的函数不仅可以像普通函数那样调用,还可以作为对象,甚至作为其他函数的参数或返回值。

7.1 函数的定义

7.1.1 声明函数

这是最常见的定义函数的方式。

function greet() {
  console.log('Hello, world!');
}

greet(); // 输出:Hello, world!

7.1.2 函数表达式

函数也可以作为表达式的一部分定义,并赋值给变量。

const greet = function() {
  console.log('Hello, world!');
};

greet(); // 输出:Hello, world!

7.1.3 箭头函数

ES6 引入了一种更简洁的定义函数的语法,称为箭头函数(Arrow Function)。它特别适合定义短小的匿名函数。

const greet = () => {
  console.log('Hello, world!');
};

greet(); // 输出:Hello, world!

箭头函数的简洁之处在于:

  • 当只有一个参数时,可以省略括号。
  • 当只有一行代码且返回值时,可以省略大括号和 return 关键字。
const double = x => x * 2;
console.log(double(5)); // 输出:10

7.2 函数的参数

7.2.1 传递参数

函数可以接收参数,并根据传入的参数执行相应的操作。

function greet(name) {
  console.log(`Hello, ${name}!`);
}

greet('Alice'); // 输出:Hello, Alice!

7.2.2 默认参数

可以为函数的参数设置默认值,当没有传递参数时使用该默认值。

function greet(name = 'stranger') {
  console.log(`Hello, ${name}!`);
}

greet(); // 输出:Hello, stranger!
greet('Bob'); // 输出:Hello, Bob!

7.2.3 Rest 参数

使用 rest 参数可以将函数的参数收集到一个数组中,方便处理不确定数量的参数。

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3)); // 输出:6
console.log(sum(4, 5, 6, 7, 8)); // 输出:30

7.3 返回值

函数可以通过 return 关键字返回值,调用函数时可以获取该返回值。

function add(a, b) {
  return a + b;
}

const result = add(5, 10);
console.log(result); // 输出:15

如果函数中没有 return 语句,函数默认返回 undefined

7.4 匿名函数

匿名函数就是没有名字的函数,通常作为回调函数传递。

setTimeout(function() {
  console.log('This message appears after 2 seconds');
}, 2000);

7.5 回调函数

回调函数是作为参数传递给其他函数并在稍后执行的函数。

function greetUser(name, callback) {
  console.log(`Hello, ${name}!`);
  callback();
}

greetUser('Alice', function() {
  console.log('Callback executed!');
});

7.6 高阶函数

高阶函数是指接收函数作为参数,或者返回另一个函数的函数。

function createMultiplier(multiplier) {
  return function(num) {
    return num * multiplier;
  };
}

const double = createMultiplier(2);
console.log(double(5)); // 输出:10

const triple = createMultiplier(3);
console.log(triple(5)); // 输出:15

7.7 函数作用域和闭包

7.7.1 作用域

局部作用域:在函数内部定义的变量只能在函数内部访问,称为局部变量。

全局作用域:在函数外部定义的变量可以在代码的任何地方访问,称为全局变量。

let globalVar = 'I am global';

function myFunction() {
  let localVar = 'I am local';
  console.log(globalVar); // 可以访问全局变量
}

myFunction();
console.log(localVar); // 错误:localVar 未定义

7.7.2 闭包

闭包是指函数内部的函数可以访问外部函数的变量,即使外部函数已经执行完毕。闭包能够“记住”它的词法作用域。

function outer() {
  let count = 0;
  
  return function inner() {
    count++;
    console.log(count);
  };
}

const counter = outer();
counter(); // 输出:1
counter(); // 输出:2

7.8 立即执行函数

立即执行函数表达式(Immediately Invoked Function Expression,IIFE)是在定义之后立即执行的函数。常用于创建独立的作用域。

(function(形参) {
  console.log('I am an IIFE!');
})(实参);

7.9 this 关键字

this 关键字在函数中指向调用它的对象,箭头函数中的 this 是从外层上下文继承的。

const person = {
  name: 'John',
  greet: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.greet(); // 输出:Hello, my name is John

八,Object对象

JavaScript 中的 Object 对象是用于存储键值对数据的基本构造。它是所有对象的顶级对象,几乎所有的 JavaScript 对象都是从 Object 派生的。Object 提供了许多有用的方法来处理对象,操作键值对,以及继承和原型链相关的功能。

8.1 什么是 Object

Object 是 JavaScript 中最基础的对象类型,用来存储键值对。键(或属性名)是字符串或 Symbol 类型,而值可以是任何类型的数据,包括其他对象、数组、函数等。

8.2 如何创建对象

创建对象的方法有多种,以下是常见的几种方式:

8.2.1 对象字面量

这是最常用和最简单的方式,用花括号 {} 创建对象,并指定属性。

const person = {
  name: 'Alice',
  age: 25,
  greet: function() {
    console.log('Hello, my name is ' + this.name);
  }
};

console.log(person.name); // 输出: Alice
person.greet(); // 输出: Hello, my name is Alice

8.2.2 new Object() 构造函数

这是另一种创建对象的方式,但在现代 JavaScript 中,使用这种方法较少,通常更倾向于对象字面量。

const person = new Object();
person.name = 'Alice';
person.age = 25;
person.greet = function() {
  console.log('Hello, my name is ' + this.name);
};

8.2.3 Object.create() 方法

Object.create() 允许从一个现有对象作为原型创建一个新对象。

const prototypePerson = {
  greet: function() {
    console.log('Hello, I am ' + this.name);
  }
};

const person = Object.create(prototypePerson);
person.name = 'Bob';
person.greet(); // 输出: Hello, I am Bob

8.3 对象属性的访问与操作

8.3.1 访问属性

  • 点语法:通过点(.)访问对象的属性。

    console.log(person.name); // 输出: Bob
    
  • 方括号语法:通过方括号和字符串访问属性,适用于动态属性名或含特殊字符的属性名。

    console.log(person['name']); // 输出: Bob
    const key = 'name';
    console.log(person[key]); // 输出: Bob
    

8.3.2 修改属性

可以通过直接赋值修改对象的属性。

person.name = 'Charlie';
console.log(person.name); // 输出: Charlie

8.3.3 添加属性

对象是动态的,可以随时添加新属性。

person.gender = 'male';
console.log(person.gender); // 输出: male

8.3.4 删除属性

使用 delete 运算符可以删除对象的属性。

delete person.age;
console.log(person.age); // 输出: undefined

8.3.5 遍历对象

let obj={
    uname: 'name',
    age: 10,
    gender: '男'
}
for(let k in obj){
    console.log(k)//输出的是属性名 uname age gender
    console.log(obj[k])//输出的是属性值:name 10 男
}

8.4 对象的常用方法

JavaScript 提供了一些非常有用的 Object 对象方法。

8.4.1 Object.keys()

返回一个包含对象所有可枚举属性名的数组。

const keys = Object.keys(person);
console.log(keys); // 输出: ['name', 'gender']

8.4.2 Object.values()

返回一个包含对象所有可枚举属性值的数组

const values = Object.values(person);
console.log(values); // 输出: ['Charlie', 'male']

8.4.3 Object.entries()

返回一个包含对象所有键值对的二维数组,每个键值对是一个数组 [key, value]

const entries = Object.entries(person);
console.log(entries); // 输出: [['name', 'Charlie'], ['gender', 'male']]

8.4.4 Object.assign()

将一个或多个源对象的所有可枚举属性复制到目标对象中。

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

8.4.5 Object.freeze()

冻结对象,防止添加、删除或修改对象的属性。

const frozenObject = Object.freeze({ name: 'Alice' });
frozenObject.name = 'Bob'; // 无效,属性无法修改
console.log(frozenObject.name); // 输出: Alice

8.4.6 Object.seal()

封闭对象,不能添加或删除属性,但可以修改现有属性的值。

const sealedObject = Object.seal({ name: 'Alice' });
sealedObject.name = 'Bob'; // 可以修改
console.log(sealedObject.name); // 输出: Bob

delete sealedObject.name; // 无效,属性无法删除
console.log(sealedObject.name); // 输出: Bob

8.4.7 Object.create()

从指定的原型对象创建一个新的对象。

const animal = {
  speak() {
    console.log('Animal is speaking');
  }
};

const dog = Object.create(animal);
dog.speak(); // 输出: Animal is speaking

8.5 对象的深浅拷贝

  • 浅拷贝:只复制对象的引用,改变其中一个对象的属性会影响另一个对象。

    const obj1 = { a: 1, b: 2 };
    const obj2 = Object.assign({}, obj1);
    obj2.a = 99;
    console.log(obj1.a); // 输出: 1(obj2修改不会影响obj1)
    
  • 深拷贝:完全复制对象及其嵌套对象,两个对象之间没有任何联系。

    const obj1 = { a: 1, b: { c: 2 } };
    const obj2 = JSON.parse(JSON.stringify(obj1)); // 使用JSON方法进行深拷贝
    obj2.b.c = 99;
    console.log(obj1.b.c); // 输出: 2(深拷贝后obj1和obj2无关联)
    

8.6 对象的继承和原型

每个对象都有一个与之关联的原型(prototype)。对象可以继承其原型对象上的属性和方法。

const animal = {
  eats: true
};

const dog = Object.create(animal);
dog.barks = true;

console.log(dog.eats); // 输出: true (继承自 animal)
console.log(dog.barks); // 输出: true

九,Map集合

在 ES6(ECMAScript 2015)中,JavaScript 引入了新的集合类型 MapMap 是一种用于存储键值对的数据结构,类似于对象(Object),但提供了更丰富的功能和更好的性能。下面我们将深入了解 Map 的特性、使用方法以及与其他集合类型的区别。

什么是 Map?

  • Map 是一种 键值对(Key-Value)集合,其中的 键和值可以是任意类型,包括基本类型和引用类型。与对象不同,Map 保留了键值对的插入顺序,提供了更高效的键值对操作方法。

9.1 创建 Map

有两种方式可以创建 Map

  1. 创建空的 Map

    const map = new Map();
    
  2. 使用初始化值创建 Map

    const map = new Map([
      ['name', 'Alice'],
      ['age', 30],
      [{ city: 'New York' }, 'Location'],
    ]);
    

9.2 Map 的基本方法

9.2.1 set(key, value)

添加或更新键值对。

map.set('name', 'Bob');
map.set(1, 'Number Key');
map.set(true, 'Boolean Key');

9.2.2 get(key)

根据键获取对应的值。如果键不存在,返回 undefined

console.log(map.get('name')); // 'Bob'
console.log(map.get(1)); // 'Number Key'
console.log(map.get('unknown')); // undefined

9.2.3 has(key)

检查 Map 是否包含指定的键,返回 truefalse

console.log(map.has('name')); // true
console.log(map.has('age')); // false

9.2.4 delete(key)

删除指定的键值对,返回一个布尔值表示是否成功删除。

map.delete('name'); // true
console.log(map.has('name')); // false

9.2.5 clear()

清空所有的键值对。

map.clear();
console.log(map.size); // 0

9.2.6 size 属性

返回 Map 中键值对的数量。

console.log(map.size); // 输出当前键值对的数量

9.3 遍历 Map

Map 是可迭代的,支持多种遍历方式。

9.3.1 for...of 迭代

for (const [key, value] of map) {
  console.log(`${key}: ${value}`);
}

9.3.2 forEach 方法

map.forEach((value, key) => {
  console.log(`${key}: ${value}`);
});

9.3.3 遍历键或值

  • 遍历所有的键

    for (const key of map.keys()) {
      console.log(key);
    }
    
  • 遍历所有的值

    for (const value of map.values()) {
      console.log(value);
    }
    
  • 遍历所有的键值对

    for (const [key, value] of map.entries()) {
      console.log(`${key}: ${value}`);
    }
    

9.4 Map 与 Object 的区别

  1. 键的类型

    • Map:键可以是任意类型,包括对象、函数、基本类型等。
    • Object:键只能是字符串或 Symbol
  2. 键的顺序

    • Map:按照键值对插入的顺序维护。
    • Object:键的顺序不确定,取决于引擎实现。
  3. 大小(Size)

    • Map:使用 size 属性获取键值对的数量。
    • Object:需要手动计算键的数量,如使用 Object.keys(obj).length
  4. 性能

    • Map:在频繁添加、删除键值对的情况下,性能更好。
    • Object:性能相对较差,特别是在处理大量键值对时。
  5. 迭代性

    • Map:本身是可迭代的,直接使用 for...of
    • Object:需要使用 Object.keys()Object.values()Object.entries()

9.5 示例:使用对象作为键

const objKey = { id: 1 };
const map = new Map();

map.set(objKey, 'Object Key');
console.log(map.get(objKey)); // 'Object Key'

9.6 常见的 Map 操作示例

9.6.1 合并两个 Map

const map1 = new Map([
  ['a', 1],
  ['b', 2],
]);

const map2 = new Map([
  ['b', 3],
  ['c', 4],
]);

const mergedMap = new Map([...map1, ...map2]);
console.log(mergedMap);
// Map { 'a' => 1, 'b' => 3, 'c' => 4 }

9.6.2 将 Map 转换为数组

const map = new Map([
  ['a', 1],
  ['b', 2],
]);

const keyArray = [...map.keys()]; // ['a', 'b']
const valueArray = [...map.values()]; // [1, 2]
const entryArray = [...map.entries()]; // [['a', 1], ['b', 2]]

9.6.3 将数组转换为 Map

const arr = [
  ['a', 1],
  ['b', 2],
];

const map = new Map(arr);
console.log(map);
// Map { 'a' => 1, 'b' => 2 }

9.7 注意事项

  • 键的相等性判断Map 使用 SameValueZero 算法判断键是否相等,类似于 ===,但 NaN 被认为等于自身。

    map.set(NaN, 'Not a Number');
    console.log(map.get(NaN)); // 'Not a Number'
    
  • 避免混淆类型:由于键可以是任意类型,确保在使用时类型一致,避免不必要的错误。

十,内置函数

JavaScript 提供了许多常用的内置对象,这些对象和类可以帮助开发者在各种场景下处理数据、操作 DOM、进行网络请求等。常用的内置对象包括:

10.1 String

  • String 对象用于处理和操作文本数据。字符串是不可变的,且有许多用于字符串操作的方法。

    常用方法:

    • length:返回字符串的长度。
    • toUpperCase():将字符串转换为大写。
    • toLowerCase():将字符串转换为小写。
    • slice():提取字符串的子字符串。
    • replace():替换匹配的子字符串。
    • split():将字符串拆分为数组。

    示例:

    const text = "Hello, World!";
    console.log(text.toUpperCase());  // "HELLO, WORLD!"
    

10.2 Number

  • Number 对象用于处理和操作数字,包括整数和浮点数。

    常用方法和属性:

    • isNaN():判断值是否为非数字。
    • isFinite():判断值是否为有限数。
    • parseFloat():将字符串转换为浮点数。
    • parseInt():将字符串转换为整数。
    • toFixed():将数字格式化为指定小数位的字符串。

    示例:

    const num = 123.456;
    console.log(num.toFixed(2));  // "123.46"
    

10.3 Math

  • Math 是一个包含数学常量和函数的对象。它不作为构造函数使用,所有方法和属性都直接调用。

    常用方法:

    • Math.max():返回多个数中的最大值。
    • Math.min():返回多个数中的最小值。
    • Math.round():对数字进行四舍五入。
    • Math.random():返回 0 到 1 之间的随机数。
    • Math.floor():向下取整。

    示例:

    const randomNum = Math.random() * 10;
    console.log(Math.floor(randomNum));  // 0 到 9 之间的整数
    

10.4 Date

  • Date 对象用于处理日期和时间。它可以创建、操作和格式化日期及时间。

    常用方法:

    • Date.now():返回当前时间的时间戳(自 1970-01-01 起的毫秒数)。
    • getFullYear():返回年份。
    • getMonth():返回月份(0-11)。
    • getDate():返回日期(1-31)。
    • getDay():返回星期几(0-6)。
    • getTime():返回时间戳。

    示例:

    const now = new Date();
    console.log(now.getFullYear());  // 当前年份
    

10.5 RegExp`(正则表达式)

  • RegExp 对象用于定义和处理正则表达式,常用于文本匹配和替换。

    常用方法:

    • test():测试字符串是否匹配正则表达式。
    • exec():返回匹配结果数组。
    • match():返回所有匹配的字符串。
    • replace():替换匹配的字符串。

    示例:

    const pattern = /hello/i;
    const result = pattern.test("Hello, World!");
    console.log(result);  // true
    

10.6 JSON

  • JSON 对象用于解析和序列化 JSON 格式的数据(JavaScript Object Notation)。

    常用方法:

    • JSON.parse():将 JSON 字符串解析为 JavaScript 对象。
    • JSON.stringify():将 JavaScript 对象序列化为 JSON 字符串。

    示例:

    const jsonString = '{"name": "Alice", "age": 25}';
    const person = JSON.parse(jsonString);
    console.log(person.name);  // 输出: Alice
    

10.7 Symbol

  • Symbol 是一种独特且不可变的数据类型,通常用作对象属性的唯一标识符。

    示例:

    const sym = Symbol('description');
    const obj = {
      [sym]: 'value'
    };
    console.log(obj[sym]);  // 输出: value
    
响应式网页 2026-06-09
操作dom 2026-06-09

© 2026 苏叶的belog