Skip to content

MDN - JavaScript

核心语法基础

1、JavaScript的定义

是一种运行在客户端(浏览器)编程语言,可以用来创建动态更新的内容,控制多媒体、制作图像动画等交互效果。

一种直译式脚本语言,一种动态类型、弱类型、基于原型的语言。

组成部分

  • 核心(ECMAScript):描述该语言的语法和基本对象
  • 文档对象模型(DOM):描述处理网页内容的方法和接口
  • 浏览器对象模型BOM):描述与浏览器进行交互的方法和接口

2、JavaScript 书写位置

1)、内部 JavaScript

在 HTML 中嵌入 JavaScript 脚本(内嵌式)

html
<script type="text/javascript">
  JavaScript代码
</script>

⚠️ 注:将 script 标签放在 附近的原因:浏览器会按照代码在文件中的 HTML。

2)、外部 JavaScript

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

html
<script type="text/javascript" src="JavaScript文件名.js"></script>

⚠️ 注:script 标签中间,否则会被忽略!

外部 JavaScript 会使代码更加有序,更易于复用,且没有了脚本的混合,HTML 也会更加易读

3)、行内 JavaScript

代码写在标签内部,直接编写在元素的事件属性中(所有 on 开头的属性名)

html
<input type="button" value="Press Me" onclick="alert('Hello World');">

<!-- 伪URL方法(在a标签href属性写入js代码)-->
<a href="javascript:alert('Hello World');">Click</a>

3、js 的注释和结束符

  • 单行注释

    • 符号://
    • 作用:// 右边这一行的代码会被忽略
    • 快捷键:ctrl+/
  • 块注释,多行注释

    • 符号:/* */
    • 作用:在 /* 和 */ 之间的所有内容都会被忽略
    • 快捷键:alt+shift+a
  • 结束符

    • 作用:使用英文的 ; 代表语句结束
    • 实际情况:实际开发中,可写可不写,浏览器(JavaScript 引擎)可以自动推断语句的结束位置
    • 约定:为了风格统一,结束符要么每句都写,要么每句都不写(按照团队要求)

输入输出语句

交互: → 数据处理 → 展示给用户

1、输入

js
prompt('请输入你的姓名')
作用:显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

2、输出

js
// 语句1
alert('页面警示框输出的内容')
作用:页面弹出警告框

// 语句2
document.write('向页面文档输出的内容')
作用:在body标签内输出内容
document.write('<h1>h1内容</h1>')
提示:如果输出的内容写标签,也会被解析成网页元素

// 语句3
console.log('控制台输出内容')
作用:控制台输出语法,程序员调试使用

// 语句4
innerHTML写入HTML元素

变量

变量是计算机中用来存储数据容器(盒子)

作用:记录计算机中数据的不同状态

⚠️ 注:变量不是数据本身,它们仅仅是一个用于存储数值的容器,可以理解为是一个个用来装东西的纸箱子。

1、声明变量

要想使用变量,首先需要创建变量(也称为声明变量或者定义变量)

js
var 变量名
let 变量名

* 声明变量有两部分构成:声明关键字、变量名(标识)
* let即关键字(let:允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语

2、变量赋值

定义了一个变量后,就能够初始化它(赋值)。在变量名之后跟上一个“=”,然后是数值。

⚠️ 注:数字直接存储,字符用单引号引起来,表示一段信息

js
变量名 =
let age
age = 18

let age = 18

简写:也可以声明变量的时候直接完成赋值操作,这种操作也称为变量初始化

当对某个值进行操作时,使用变量

3、更新变量

变量赋值后,还可以通过简单地给它一个不同的值来更新它。

js
let age = 18
age = 19
console.log(age)  // 19

// 变量不能重复声明
// 未捕获的语法错误:标识符age已经被定义了
// Uncaught SyntaxError: Identifier 'age' has already been declared

⚠️ 注:let 不允许对同一个变量多次声明

4、声明多个变量

多个变量中间用逗号隔开

js
// 不是很直观,可读性较差
let age = 18, sex = '女'

// 建议一个变量占一行,可读性更好
let age = 18
let sex = '女'

内存:计算机中存储数据的地方,相当于一个空间

  • 字节:Byte
  • GB = 1024 MB
  • MB = 1024 KB
  • KB = 1024 B
  • Byte = 8 bit

变量本质:是程序在内存中申请的一块用来存放数据的小空间

5、变量命名规则与规范

规则:

  • 不能用关键字

  • 关键字:有特殊含义的字符,JavaScript 内置的一些英文词汇。例如:let、var、if、for 等

  • 只能用下划线、字母、数字、$ 组成,且数字不能开头

  • 字母严格,如 Age 和 age 是不同的变量

规范:

  • 见名知意,起名要有意义
  • 遵守小驼峰命名法
    • 第一个单词首字母小写,后面每个单词首字母大写。例:userName

关键字、保留字、true、false、null 并不能作为标识符

  • 常见关键字
breakelsenewvar
casefinallyreturnvoid
catchforswitchwhile
continuefunctionthiswith
defaultifthrow
deleteintry
doinstanceoftypeof
  • 常见保留字
abstractenumintshort
booleanexportinterfacestatic
byteextendslongsuper
charfinalnativesynchronized
classfloatpackagethrows
constgotoprivatetransient
debuggerimplementsprotectedvolatile
doubleimportpublic

常量

  • const
  • 定义:也是一个容器,用于保存数据的
  • 和变量的区别:常量里面保存的值是改变的
  • 使用场景:当某个值永远不会改变的时候,我们可以使用常量来保存,目的为了程序的安全

⚠️ 注:1、常量不允许重新赋值,可以理解为是只读的

2、声明的时候必须赋值(初始化)

拓展:一般情况下常量大家都习惯用全大写,_ 连接

数据类型

1、基本数据类型

number 数字型、string 字符串型、boolean 布尔型、undefined 未定义型、null 空型

1)、number

数字:可以用于运算操作,比如对数字的加减乘除等操作

js 中的整数、小数等统一称为数字类型

2)、string

字符串:通过单引号‘’、双引号“”或反引号``包裹的数据都属于字符串(必须成对出现)

单引号和双引号没有本质上的区别,推荐使用单引号

⚠️ 注:1、单引号可以互相嵌套,但是不可以自己嵌套自己(口诀:外双内单、外单内双)

2、一定注意变量名不要加引号,否则认为是字符串

反引号:解决字符串拼接的问题

字符串拼接

  • + 可以实现字符串的拼接,最常见是字符串拼接变量
  • 口诀:数字相加,字符相连
  • 模板字符串
    • ``拼接字符串和变量
    • `${变量名}`
    • 口诀:反引中间变量套,直接 $ 大括号
    • 反引号中间的字符串可以换行

3)、boolean

布尔型:用于判断真假的数据类型,通常用来判断条件是否成立

true:真,false:假

4)、undefined

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

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

使用场景:可以通过检测这个变量是不是 undefined,判断用户是否有数据传递过来

5)、null

仅仅是一个代表“无”、“空”或者“值未知”的特殊值

undefined 和 null 的区别:

  • undefined:没有赋值,不存在
  • null:赋值了,但是内容为空

⚠️ 注:typeof null 返回的是 object,对象类型,不代表 null 就是引用数据类型

2、引用数据类型

object 对象、Array 数组、Function 函数

运算符

1、操作符:typeof

js
typeof undefined  // undefined
typeof null  // object

2、算数运算符

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

  • + : 求和
  • - : 求差
  • * :求积
  • / : 求商
  • % : 取模(取余数)
    • 开发中经常作为某个数字是否被整除

⚠️ 注:在计算失败时,显示的结果是 NaN (not a number)

3、赋值运算符

对变量进行赋值的运算符

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

使用这些运算符可以在对变量赋值时进行快速操作,从而可以简化代码

4、自增/自减运算符

符号作用说明
++自增变量自身的值加1,例如:x++
--自减变量自身的值减1,例如:x--

⚠️ 注:1、只有变量能够使用自增和自减运算符

2、++ -- 可以在变量前面也可以在变量后面,比如 x++ 或者 ++x

  • 单独使用的时候,++ 在前和在后没有区别,如果参与运算就有区别了
  • 前缀式:++ 放在变量前面,对变量值进行 +1拿变量的值进行运算
  • 后缀式:++ 放在变量后面,拿变量值进行运算对变量的值进行 +1

5、比较(关系)运算符

使用场景:比较两个数据大小,是否相等,根据比较结果返回一个布尔值(true/false)

  • > :左边是否大于右边
  • < :左边是否小于右边
  • >= :左边是否大于或等于右边
  • <= :左边是否小于或等于右边
  • == :左右两边值是否相等
  • != :左右值不相等
表达式
null == undefinedtrue
‘NaN’ == NaNfalse
5 == NaNfalse
NaN == NaNfalse
false == 0true
true == 1true
true == 2false
undefined == 0false
null == 0false
‘100’ == 100true
‘100’ === 100false

6、逻辑运算符

使用场景:可以把多个布尔值放到一起运算,最终返回一个布尔值

符号名称日常读法特点口诀
&&逻辑与并且符号两边有一个假的结果为假一假则假
||逻辑或或者符号两边有一个真的结果为真一真则真
!逻辑非取反true 变 false,false 变 true真变假,假变真

7、运算符优先级

优先级顺序
1()
2++ -- !
3先 * / % 后 + -
4> >= < <=
5== != === !==
6先 && 后 ||
7=

数据类型转换

把一种数据类型转换成另外一种数据类型

1、转数字

  • Number()
    • 成功,返回一个数字类型
    • 无法转换混合字符串,会返回 NaN
  • parseInt()
    • 只保留
    • 开头是数字,会自动舍弃数字后的字符串
    • 必须保证开头是数字,否则返回 NaN
  • parseFloat()
    • 可以保留
    • 注意事项同 parseInt()

布尔型转换成数字:true 为 1 ,false 为 0

null 转换成数字为 0,undefined 为 NaN

2、转字符串

  • String()
  • 变量.toString(进制)

3、转布尔

  • Boolean()

    • 返回 true 或 false

    • 如果值为 false、0、‘’、null、undefined、NaN,则返回 false,其余返回为 true

隐式转换

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

  • 转数字
    • 算术运算符:-、*、/、%,比较运算符 > == 等
    • + 号作为正号可以把字符串转换成数字型
  • 转字符串
    • + 加号字符串拼接
  • 转布尔值
    • ! 逻辑非
js
// 1、转数字型
let age = '18'
console.log(age - 2)
console.log(age < 20)

// 2、转字符串型
let age = '18'
console.log(age + '岁')  // string:18岁

// 3、转布尔型
// age不是布尔值,所以会先隐式转换成布尔值,后取反
let age = 18
console.log(!age)  // false

例:实际开发场景中的登录功能,登录成功后,服务器会给一个令牌让我们存储起来,可以根据本地是否有这个令牌来判断用户是否登录,即 !str

转义符

字面量含义
\n换行
\t制表
\b空格
\r回车
\f进纸
\ \斜杠
\ '单引号
\ ''双引号

表达式和语句

表达式:可以的代码,并将其计算出一个结果

语句:一段的代码,是一个,例如分支语句和循环语句

编程三大结构

顺序结构:从上往下依次执行

分支结构:根据条件选择执行代码

循环结构:某段代码被重复执行

编程三大结构.png

1、分支语句

根据条件判定真假,来选择性地执行想要的代码

1)、if 语句

js
// 单分支语句
if (条件) {
  满足条件要执行的代码
}

// 双分支语句
if (条件) {
  满足条件要执行的代码
} else {
  不满足条件执行的代码
}

// 多分支语句
if (条件1) {

} else if (条件2) {

} else {

}
  • 小括号内的条件结果是布尔值,为 true 时,进入大括号里执行代码;为 false,则不执行
  • 小括号内的结果不是布尔值,会发生类型转换为布尔值,类似 Boolean()
  • 如果大括号只有一个语句,大括号可以省略

2)、三元运算符

使用场景:一些简单的双分支,可以使用三元运算符,写起来比 if else 双分支更简单

js
// 如果满足条件true就执行表达式1,否则就执行表达式2
条件 ? 表达式1 : 表达式2

3)、switch 语句

使用场景:适用于有多个条件的时候,也属于分支语句,大部分情况下和 if 多分支语句功能相同

js
// 找到跟小括号里数据全等的case值,并执行里面对应的代码
// 若没有全等===的则执行default里的代码

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

注意:

  • switch 语句一般用于等值判断,if 适用于区间判断

  • switch 一般需要配合 break 关键字使用,没有会造成 case 穿透

  • if 多分支语句开发要比 switch 更重要,使用也更多

2、循环结构

1)、while 循环(先验证后循环)

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

2)、do-while 循环(先循环后验证)

js
do{
  // 循环体(先执行一次)
} while (循环条件)

3)、for循环(先判断后循环)

js
for (初始值;循环条件;变量计数) {
  // 满足条件执行的循环体
}

4)、中止循环

  • break:中止整个循环,一般用于结果已经得到,后续的循环不需要的时候可以使用

  • continue:中止本次循环,一般用于排除或者跳出某一个选项的时候

无限循环

  • while(true)
  • for( ;; )

3、循环嵌套

一个循环语句里面又包含另一个循环语句

外部循环每循环一次,内部循环执行所有次

js
for (初始值;循环条件;变量计数) {
  for (初始值;循环条件;变量计数) {
  
  }
}

数组

1、数组定义

定义:连续的储存空间

  • 数组是按顺序保存(有序),所以每个数据都有自己的编号
  • 编号从 0 开始,数据的编号经常称为索引或下标
  • 数组可以存储任意类型的数据

2、创建数组

1)、通过字面量创建

js
let 数据名 = [数据1, 数据2, ..., 数据n]

2)、通过构造器创建

js
let arr = new Array()
let arr = new Array(5)  // 创建长度为5的数组
let arr = new Array("朱一龙", 4, 16)  // 创建有数据的数组

3、引用数组

  • 通过数组下标添加

  • 通过 for 循环遍历

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

4、常用方法

数组的方法:增 删 改 查

1)、增

  • push(新增数据):在数组末尾添加
  • unshift(新增数据):在数组开头添加

返回值:该数组的新长度,都会修改原数组

2)、删

  • pop():删除数组的最后一个元素

  • shift():删除数组的第一元素

    返回值:被删除的那个元素

  • splice(起始下标,删除个数)删除指定项

3)、改

  • 数组下标直接赋值:数组[索引] = 新值

    返回值:如果下标不存在,则是新增一个数组元素,并修改了数组长度(尽量避免)

  • 插入:splice(起始下标,0,插入内容)

  • 替换:splice(起始下标,删除个数,替换内容)

⚠️ 注:修改替换 :注意第二个参数代表删除几个

如果删除 0 个则代表插入

删除 1 个则第三个参数值会进行插入,插入在下标为 1 的位置上

4)、查

语法:数组[索引]

返回值:如果查询不到则返回 undefined

5)、合并:concat

js
let arr1 = [123,'234',true]
let arr2 = [false,'hahah']
let arr3 = arr1.concat(arr2)  // [123, '234', true, false, 'hahah']

⚠️ 注:谁调用 concat 的方法,谁就在前面

concat 合并方法,既不会改变 arr1 也不会改变 arr2,会生成一个新的数组

6)、抽取截取

js
slice(起始下标【要被截取】,结束下标【不会被截取】)

⚠️ 注:slice 方法也会生成一个新数组,原数组不会发生改变

7)、串联:join()

js
let arr = [1,2,3,5,6,6,3,3,1,3,4,6]
let newArr = arr.join("*")
// 把数组的每一项都获取出来并将*把他们连接变成一个字符串
console.log(newArr)

8)、反转:reverse()

⚠️ 注:会改变原数组

9)、清空数组

  • var arr=[]
  • arr.length = 0
  • arr.splice(0,arr.length)

10)、排序:sort()

会修改原数组

js
let arr = [4, 5, 2, 1, 3]

// 升序排序
arr.sort(function (a, b) {
  return a - b
})

// 降序排序
arr.sort(function (a, b) {
  return b - a
})

// 随机排序
arr.sort(function (a, b) {
	return Math.random() - 0.5  //返回值的正负概率分别为50%,故升降序排列是随机的
})

选择排序原理:就是从第一个数开始,与后面所有的数相比较,找出最小(最大)的数,放在第一个位置,以此类,每一轮确定一个相对于这一轮最小(最大)的数

核心:利用循环嵌套比较,根据索引号来交换变量

①:外层循环是一共进行几轮相比较,通过观察,一共进行 次比较

  • for (let i = 0; i < ; i++)
  • 把 i 作为最小值起始索引

②:里层循环是每一轮的比较来查找最小值

  • 里层循环起始值是 个元素开始查找
  • for (let j = ; j < arr.length; j++)
  • 进行比较的时候,发现最小的数组元素,把当前元素

③:如果 ,则交换变量

js
let arr = [44, 33, 22, 11]

// 外层循环控制比较的趟数
// 内层循环控制两两比较的次数
// [44, 33, 22, 11]
// 永远都是minIndex和i的位置进行调换
// i = 0 [11, 33, 22, 44]
// i = 1 [11, 22, 33, 44]
// i = 2 [11, 22, 33, 44]

// 通过嵌套循环来实现选择排序
for (let i = 0; i < arr.length - 1; i++) {
  // 一次遍历, 只能找到一个最小值
  let minIndex = i
  for (let j = i; j < arr.length; j++) {
    if (arr[j] < arr[minIndex]) {
      minIndex = j
    }
  }
  // console.log(minIndex)
  // 进行交换
  // 谁和谁交换?minIndex和i对应的值进行交换
  // if (i !== minIndex) {
  let temp = arr[i]
  arr[i] = arr[minIndex]
  arr[minIndex] = temp
  // }
}
console.log(arr)

算法可视化网站: https://visualgo.net/zh/sorting

函数

1、基本使用

函数:是可以被重复使用的代码块

作用:函数可以把具有相同或相似逻辑的代码“包裹”起来,有利于代码复用

声明(定义)一个完整函数包括关键字、函数名、形式参数、函数体、返回值 5 个部分

js
// 声明(定义)函数:利用关键字function定义函数 
function 函数名() {
  函数体
}

// 调用函数:可以重复调用
函数名()

⚠️ 注:1、函数名命名跟变量一致,采用 小驼峰 命名法

2、函数名经常采用动词

js
function sum(参数1, 参数2...) {
  return 结果
}
console.log(sum(1, 2))  // 输出函数返回的结果
  • 函数参数,如果有多个则用逗号分隔,用于接受传递过来的数据
  • return 关键字可以把结果返回给调用者

2、函数参数

通过向函数传递参数,可以让函数更加灵活多变

形参:时小括号里的叫形参(形式上的参数)

实参:时小括号里的叫实参(实际上的参数)

执行过程: 会把实参的数据传递给形参,从而提供给函数内部使用,我们可以把形参理解为变量

js
// 形参和实参个数不匹配

// 1、形参个数过多,会自动补充undefined 
function sum(x, y) {  // 形参 
  return x + y
}
console.log(sum(1, 2))  // 实参 3
console.log(sum(1))  // 实参 NaN, 1 + undefined = NaN

// 2、实参个数过多,则多余的实参会被忽略
console.log(sum(1, 2, 3)) // 实参 3

// 3、开发中提倡要保证实参和形参个数统一

在 js 中 实参的个数和形参的个数可以不一致

  • 如果形参过多,会自动填上 undefined
  • 如果实参过多,那么多余的实参会被忽略

3、逻辑中断

逻辑中断: 存在于逻辑运算符 && 和 || 中,左边如果满足一定条件会中断代码执行,也称为逻辑短路

js
false && anything  // 逻辑与左边false则中断,如果左边为true,则返回右边代码的值

true || anything  // 逻辑或左边true则中断,如果左边为false,则返回右边代码的值
js
// 例子
// 1、逻辑与中断:如果左边为假,则中断,如果左边为真,则返回右边的值
console.log(false && 1 + 2)  // false
console.log(0 && 1 + 2)  // 0
console.log('' && 1 + 2)  // ''
console.log(undefined && 1 + 2)  // undefined
console.log(true && 1 + 2)  // 3:此处不会发生逻辑中断
console.log(1 && 1 + 2)  // 3:此处不会发生逻辑中断

// 2、逻辑或中断,如果左侧为真,则中断,如果左侧为假,则返回右边的值
console.log(true || 1 + 2) // true:发生了中断
console.log(1 || 1 + 2) // 1:发生了中断
console.log(false || 1 + 2) // 3:此处不会发生逻辑中断

// 3、使用场景
function sum(x, y) {  // x = undefined
  //  x = undefined || 0
  // x = 1 || 0
  x = x || 0
  y = y || 0
  return x + y
}
console.log(sum())  // 0
console.log(sum(1, 2)) // 3

4、函数默认参数

默认参数:可以给形参设置默认值

这个默认值只会在缺少实参传递或者实参是 undefined 才会被执行

默认参数和逻辑中断使用场景区别:

  • 默认参数主要处理(处理参数要比逻辑中断更简单)
  • 逻辑中断还可以处理更多的需求
js
// 默认参数: 给形参一个默认值
// 默认参数里面的值执行:
// 1、没有实参传递过来x=0 
// 2、有实参传递但是传递的是undefined,x=0
function sum(x = 0, y = 0) {
  return x + y
}
console.log(sum())  // 0
console.log(sum(undefined, undefined))  // 0
console.log(sum(1, 2))  // 3

5、函数返回值

返回值:把处理结果返回给调用者

函数的本质是封装(包裹),函数体内的逻辑执行完毕后,函数外部如何获得函数内部的执行结果呢?

要想获得函数内部逻辑的执行结果,需要通过 return 这个关键字,将内部执行结果传递到函数外部,这个被传递到外部的结果就是返回值。

js
// 函数返回值细节
// 1、return结束函数,return后面的代码不会执行了,break退出循环或者switch
function sum(x, y) {
  return x + y
  console.log('我不会执行')
}
console.log(sum(1, 3))

// 2、return和被返回的结果不要换行
function sum(x, y) {
  return
  x + y
}
console.log(sum(1, 3))

// 3、如果函数没有return,则默认返回的是undefined
function fn() {}
console.log(fn())  // undefined
  • 结束函数:return会立即结束当前函数,所以后面代码不会再被执行
  • 不要换行:在 return 关键字和被返回的表达式之间不允许使用换行符,否则内部执行相当于会自动补充分号
  • 默认返回:函数可以没有 return,这种情况函数默认返回值为 undefined

6、作用域

作用域(scope): 变量或者值在代码中可用性的范围

作用:作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

1)、全局作用域

作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件

处于全局作用域内的变量,称为全局变量,可以被任意地方访问和修改

2)、局部作用域

  • 函数作用域。作用于函数内的代码环境
  • 块级作用域。{ } 大括号内部

处于局部作用域内的变量,称为局部变量,只能在当前作用域中访问和修改

⚠️ 注:1、如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐

2、但是有一种情况,函数内部的形参可以看做是局部变量。

变量的访问原则

访问原则:在能够访问到的情况下先局部,局部没有再找全局,总结: 就近原则

7、匿名函数

  • 具名函数:带有名字的函数(只要能够访问到函数,就可以调用,不用看声明的时机和顺序)

  • 匿名函数:没有名字的函数,无法直接使用

1)、函数表达式

将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们将这个称为函数表达式

js
// 声明
let fn = function() {
  console.log('函数表达式')
}
// 调用
fn()
  • 其实函数也是一种数据类型
  • 函数表达式必须先定义,后使用
  • 函数的形参和实参使用跟具名函数一致

2)、立即执行函数

IIFE(立即执行函数表达式)(Immediately Invoked Function Expression)

场景介绍:避免全局变量之间的污染

注意:多个立即执行函数要用 ; 隔开,要不然会报错

js
(function(){
  
})();

(function(){
  
}());

对象

对象(Object):JavaScript 里的一种数据类型(引用类型),也是用于存储数据

好处:可以用来详细的描述某个事物,是用键值对形式存储语义更明了

特点:对象数据是无序的,数组有序的

1、对象基本使用

对象有属性和方法组成

1)、对象属性

数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。

  • 属性都是成对出现的,包括属性名和值,它们之间使用 : 分隔
  • 多个属性之间使用 , 分隔
  • 属性就是依附在对象上的变量(对象外是变量,对象内是属性)
js
// 定义对象属性
let person = {
  sex: '女',
  age: 18,
  uname: '呆呆',
  weight: 12.6
}

// 访问对象属性  
// 语法:对象.属性
console.log(person.age)  // 18
console.log(person.weight)  // 12.6

2)、对象方法

数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。

  • 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
  • 多个属性之间使用 , 分隔
  • 方法是依附在对象中的函数(对象外是函数,对象内是方法)
js
let person = {
  uname: '呆呆',
  // 定义对象方法
  sing: function () {
    console.log('唱歌')
  },
  dance: function () {
    console.log('跳舞')
  },
  sum: function (x, y) {  // 2
    // console.log(x + y)
    return x + y
  }
}

console.log(pig)

// 调用对象方法
person.sing()  // 唱歌
person.dance()  // 跳舞

// 方法可以传递参数也可以有返回值,跟函数使用基本类似
let re = person.sum(1, 2)  // 1:实参
console.log(re)

⚠️ 注:无论是属性或是方法,同一个对象中出现名称一样的,后面的会覆盖前面的

2、操作对象

对象本质是无序的数据集合,操作对象数据无非就是 增 删 改 查

  • 查询:对象.属性对象.方法

  • 修改:对象.属性 = 新值

  • 增加:对象.新属性 = 新值

    对象.新方法名 = function(){}

  • 删除:delete 对象名.属性名

js
let person = {
  uname: '呆呆',
  sing: function () {
    console.log('唱歌')
  }
}

// 1、查
console.log(person.uname)
person.sing()

// 2、增
person.age = 4
person.dance = function () {
  console.log('跳舞')
}
console.log(pig)

// 3、改
person.uname = '小猪'
person.sing = function () {
  console.log('哼哼哼!!')
}
console.log(person)

// 4、删
delete pig.age
delete pig.dance
console.log(pig)

查找属性的另外写法

对于多词属性比如中横线分割的属性,点操作就不能用了

我们可以采取:对象['属性'] 方式, 单引号和双引号都可以,当然也可以用于其他正常属性

js
let person = {
  // 属性名如果是非法字符,可以通过''变成字符串,合法的存储到对象中
  'u-name': '呆呆',
  age: 4
}

// console.log(person.u-name)  // NaN
console.log(person['u-name'])  // 呆呆
console.log(person['age'])  // 4 === person.age

总结:多词属性或者需要解析变量的时候使用 [] 语法,其余的直接使用点语法

3、遍历对象

for 遍历对象的问题:对象没有长度 length,而且是无序的

javascript
for (let 变量 in 对象) {
  console.log(变量)  // 属性名
  console.log(对象[变量])  // 属性值
}
  • for in 语法中的 k 是一个变量, 在循环的过程中依次代表对象的属性名
  • 由于 k 是变量, 所以必须使用 [] 语法解析
  • 一定记住: k 是获得对象的属性名, 对象名[k] 是获得属性值
  • 一般不用这种方式遍历数组、主要是用来遍历对象
js
// 遍历对象
let person = {
  sex: '女',
  age: 4,
  uname: '呆呆',
  weight: 12.6,
}

for (let key in person) {
  console.log(key)  // key是属性:对象.属性
  // console.log(person.key)
  // person.key  undefined,因为key是个变量不是属性
  // key:'sex'、'age' 对象[key]:对象['sex']、对象['age']
  console.log(person[key])
}


// 注意:数组遍历用传统for,for in主要用来遍历对象
let arr = ['red', 'green', 'pink']
for (let k in arr) {
  console.log(k)  // 得到字符串类型的索引号
}

内置对象

JavaScript 内部提供的对象,包含各种属性和方法给开发者调用

  • document.write()
  • console.log()

1、Math 对象

JavaScript 提供的一个“数学”对象,提供了一系列做数学运算的方法

Math 对象在线文档

属性/方法作用例子
PI圆周率Math.PI 属性,返回圆周率
max找最大值Math.max(8, 3, 1) 方法,返回 8
min找最小值Math.min(8, 3, 1) 方法,返回 1
abs绝对值Math.abs(-1) 方法,返回 1
ceil向上取整Math.ceil(3.1) 方法,返回 4
floor向下取整Math.floor(3.8) 方法,返回 3
round四舍五入取整Math.round(3.8) 方法,返回 4, 遇到.5则舍入到相邻的在正无穷(+∞)方向上的整数
sqrt()平方根
pow(数值,几次方)次方计算

1)、随机数 random

Math.random():随机数,返回一个 0 - 1 之间,并且包括 0 不包括 1 的随机小数

2)、取整

js
// 0~10整数
Math.floor(Math.random()*(10 + 1))

// 8~18整数
Math.floor(Math.random()*(10 + 1)) + 8

// 12~25整数
Math.floor(Math.random()*(13 + 1)) + 12

// n~m整数,包含n和m
Math.floor(Math.random()*(差值 + 1)) + 起点

数据存储

js 数据类型分类:

  • 基本数据类型(简单数据类型)
  • 引用数据类型(复杂数据类型)

内存中堆栈空间分配区别:

  • 栈:优点访问速度快,基本数据类型存放到栈里面

    栈

  • 堆:优点存储容量大,引用数据类型存放到堆里面

    引用类型变量(栈空间)里存放的是地址,真正的数据存放在堆空间

    堆

js
// 例子1
let x = 10
let y = x
x = 20
console.log(y)  // 10

// 例子2
let obj1 = {
  age: 10
}
let obj2 = obj1
obj1.age = 20
console.log(obj2)  // { age: 20 }

声明变量总结

建议: const 优先,尽量使用 const,原因是:

  • 很多变量声明的时候明确不会被更改了,为了安全性,那为什么不用 const 呢?
  • 实际开发中也是,比如 React、Vue,基本 const 声明
  • 有了变量先给 const,如果发现它后面是要被修改的,再改为 let
js
// 不可以把let改为const
let x = 10
x = x + 20
console.log(x)

// 可以把let改为const,跟堆内存有关
let arr = ['blue', 'green']
arr.push('pink')
console.log(arr)

arr = ['purple']  // 此时不可以把let改为const,相当于修改了数组,产生了新的堆内存

// 可以把let改为const
let person = {
  name: '呆呆',
  age: 18
}
person.sex = '女'
console.log(person)

⚠️ 注:什么时候使用 const 不会出错?就看有没有对变量直接赋值

welcome to zhudaidai's blog!