js第二天
十一.函数
1.函数的定义
声明式
function test1(){
console.log("lol")
}
function test2(){
console.log("apex")
}
test1()//调用函数阶段;选择了test1所以结果为lol
赋值式
var test3=function(){
console.log("csgo")
}
var test4=function(){
console.log("g7人")
}
test3()//结果为csgo
两种方法都可调用多次函数
2.函数的参数
定义和调用函数的时候里面的()是用来放参数的位置,参数分为行式参数和实际参数。
function test(a,b){//行参
var 套餐一=a===1?"米饭":"土豆丝"//可选择
var 套餐二=b===2?"馒头":"脆皮鸭"
var 套餐三="盖浇面"//规定好的套餐
console.log(套餐一,套餐二,套餐三)
}
test(1,3)//实参
可以传参,可以不传参
形参只能在函数内部使用
内部定义只有内部才能访问
console.error("请输入参数")//报错
3return
返回值
- 函数调用本身也是一个表达式,表达式就应该有一个值出现
- 现在函数执行完毕之后,是不会有结果出现的
// 比如 1 + 2 是一个表达式,那么 这个表达式的结果就是 3
console.log(1 + 2) // 3
function fn() {
// 执行代码
}
// fn() 也是一个表达式,这个表达式就没有结果出现
console.log(fn()) // undefined
- return关键字就是可以给函数执行完毕一个结果
function fn() {
// 执行代码
return 100
}
// 此时,fn() 这个表达式执行完毕之后就有结果出现了
console.log(fn()) // 结果为100
我们可以在函数内部使用return关键把任何内容当作这个函数运行后的结果
中断函数
- 当我开始执行函数以后,函数内部的代码就会从上到下的依次执行
- 必须要等到函数内的代码执行完毕
- 而 return 关键字就是可以在函数中间的位置停掉,让后面的代码不在继续执行
function fn() {
console.log(1)
console.log(2)
console.log(3)
// 写了 return 以后,后面的 4 和 5 就不会继续执行了
return
console.log(4)
console.log(5)
}
// 函数调用
fn()
4.预解析
解释代码
- 因为是在所有代码执行之前进行解释,所以叫做 预解析(预解释)
- 需要解释的内容有两个
1.声明式函数
在内存中先声明有一个变量名是函数名,并且这个名字代表的内容是一个函数
2.var 关键字
在内存中先声明有一个变量名
fn()
console.log(num)
function fn() {
console.log('我是 fn 函数')
}
var num = 100
预解析之后
var num=100
function fn() {
console.log('我是 fn 函数')
}
fn()
console.log(num
赋值式函数会按照 var 关键字的规则进行预解析
5.作用域
- 什么是作用域,就是一个变量可以生效的范围
- 变量不是在所有地方都可以使用的,而这个变量的使用范围就是作用域
全局作用域
- 全局作用域是最大的作用域
- 在全局作用域中定义的变量可以在任何地方使用
- 页面打开的时候,浏览器会自动给我们生成一个全局作用域 window
- 这个作用域会一直存在,直到页面关闭就销毁了
// 下面两个变量都是存在在全局作用域下面的,都是可以在任意地方使用的
var num = 100
var num2 = 200
局部作用域
- 局部作用域就是在全局作用域下面有开辟出来的一个相对小一些的作用域
- 在局部作用域中定义的变量只能在这个局部作用域内部使用
- 在 JS 中只有函数能生成一个局部作用域,别的都不行
- 每一个函数,都是一个局部作用域
// 这个 num 是一个全局作用域下的变量 在任何地方都可以使用
var num = 100
function fn() {
// 下面这个变量就是一个 fn 局部作用域内部的变量
// 只能在 fn 函数内部使用
var num2 = 200
}
fn()
6.变量使用规则
- 有了作用域以后,变量就有了使用范围,也就有了使用规则
- 变量使用规则分为两种,访问规则 和 赋值规则
访问规则
- 当我想获取一个变量的值的时候,我们管这个行为叫做 访问
- 获取变量的规则:
首先,在自己的作用域内部查找,如果有,就直接拿来使用
如果没有,就去上一级作用域查找,如果有,就拿来使用
如果没有,就继续去上一级作用域查找,依次类推
如果一直到全局作用域都没有这个变量,那么就会直接报错(该变量 is not defined)
var num = 100
function fn() {
var num2 = 200
function fun() {
var num3 = 300
console.log(num3) // 自己作用域内有,拿过来用
console.log(num2) // 自己作用域内没有,就去上一级,就是 fn 的作用域里面找,发现有,拿过来用
console.log(num) // 自己这没有,去上一级 fn 那里也没有,再上一级到全局作用域,发现有,直接用
console.log(a) // 自己没有,一级一级找上去到全局都没有,就会报错
}
fun()
}
fn()
控制台结果为
300
200
100
is not defined
- 变量的访问规则 也叫做 作用域的查找机制
- 作用域的查找机制只能是向上找,不能向下找
function fn() {
var num = 100
}
fn()
console.log(num) // 发现自己作用域没有,自己就是全局作用域,没有再上一级了,直接报错
赋值规则
- 当你想给一个变量赋值的时候,那么就先要找到这个变量,在给他赋值
- 变量赋值规则:
先在自己作用域内部查找,有就直接赋值
没有就去上一级作用域内部查找,有就直接赋值
还没有再去上一级作用域查找,有就直接赋值
如果一直找到全局作用域都没有,那么就把这个变量定义为全局变量,再给他赋值
//无法找到上一级变量
function fn() {
num = 100
}
fn()
// fn 调用以后,要给 num 赋值
// 查看自己的作用域内部没有 num 变量
// 就会向上一级查找
// 上一级就是全局作用域,发现依旧没有
// 那么就会把 num 定义为全局的变量,并为其赋值
// 所以 fn() 以后,全局就有了一个变量叫做 num 并且值是 100
console.log(num) // 100
例子:
var num=100
function test1(){
var num=200
function child1(){
//var num=300
num=400//num=300被注释后在当前作用域找不到num赋值,向上一级进行赋值
console.log(num)
}
console.log("修改前",num)//调用之前num为200
child1()
console.log("修改后",num)//调用之后num赋值为400
}
test1()
十二.对象
- 对象是一个复杂数据类型
- 其实说是复杂,但是没有很复杂,只不过是存储了一些基本数据类型的一个集合
var obj = {
num: 100,
str: 'hello world',
boo: true
}
- 这里的 {} 和函数中的 {} 不一样
- 函数里面的是写代码的,而对象里面是写一些数据的
- 对象就是一个键值对的集合
- {} 里面的每一个键都是一个成员
- 也就是说,我们可以把一些数据放在一个对象里面,那么他们就互不干扰了
- 其实就是我们准备一个房子,把我们想要的数据放进去,然后把房子的地址给到变量名,当我们需要某一个数据的时候,就可以根据变量名里面存储的地址找到对应的房子,然后去房子里面找到对应的数据
1.创建对象
- 字面量的方式创建一个对象
// 创建一个空对象
var obj = {}
// 像对象中添加成员
obj.name = 'Jack'
obj.age = 18
- 内置构造函数的方式创建对象
// 创建一个空对象
var obj = new Object()
// 向对象中添加成员
obj.name = 'Rose'
obj.age = 20
Object 是 js 内置给我们的构造函数,用于创建一个对象使用的
2.数据类型之间存储的区别
分为 栈 和 堆
栈: 主要存储基本数据类型的内容
堆:主要存储复杂数据类型的内容
复杂数据存储
var obj = {
name: 'Jack',
age: 18,
gender: '男'
}
3.数据类型之间的比较
- 基本数据类型是 值 之间的比较
var num = 1
var str = '1'
console.log(num == str) // true
- 复杂数据类型是 地址 之间的比较
var obj = { name: 'Jack' }
var obj2 = { name: 'Jack' }
console.log(obj == obj2) // false
十三.数组
就是数据的集合,也就是我们把一些数据放在一个盒子里面,按照顺序排好。
[1, 2, 3, 'hello', true, false]
有两大类:基本数据类型和复杂数据类型
- 基本数据类型: number / string / boolean / undefined / null
- 复杂数据类型: object / function / array / …
1.创建一个数组
- 数组就是一个 []
- 在 [] 里面存储着各种各样的数据,按照顺序依次排好
字面量创建一个数组
直接使用 [] 的方式创建一个数组
// 创建一个空数组
var arr1 = []
// 创建一个有内容的数组
var arr2 = [1, 2, 3]
内置构造函数创建数组
- 使用 js 的内置构造函数 Array 创建一个数组
// 创建一个空数组
var arr1 = new Array()
// 创建一个长度为 10 的数组
var arr2 = new Array(10)
// 创建一个有内容的数组
var arr3 = new Array(1, 2, 3)
2.数组的length
length 就是表示数组的长度,数组里面有多少个成员,length 就是多少
// 创建一个数组
var arr = [1, 2, 3]
console.log(arr.length) // 3
3.数组的索引
- 索引,也叫做下标,是指一个数据在数组里面排在第几个的位置
- 注意: 在所有的语言里面,索引都是从 0 开始的
- 在 js 里面也一样,数组的索引从 0 开始
// 创建一个数组
var arr = ['hello', 'world']
- 上面这个数组中,第 0 个 数据就是字符串 hello,第 1 个 数据就是字符串 world
- 想获取数组中的第几个就使用 数组[索引] 来获取
var arr = ['hello', 'world']
console.log(arr[0]) // hello
console.log(arr[1]) // world
4.数组的排序
排序,就是把一个乱序的数组,通过我们的处理,让他变成一个有序的数组
冒泡排序
- 先遍历数组,让挨着的两个进行比较,如果前一个比后一个大,那么就把两个换个位置
- 数组遍历一遍以后,那么最后一个数字就是最大的那个了
- 然后进行第二遍的遍历,还是按照之前的规则,第二大的数字就会跑到倒数第二的位置
- 以此类推,最后就会按照顺序把数组排好了
选择排序
- 先假定数组中的第 0 个就是最小的数字的索
- 然后遍历数组,只要有一个数字比我小,那么就替换之前记录的索引
- 知道数组遍历结束后,就能找到最小的那个索引,然后让最小的索引换到第 0 个的位置
- 再来第二趟遍历,假定第 1 个是最小的数字的索引
- 在遍历一次数组,找到比我小的那个数字的索引
- 遍历结束后换个位置
- 依次类推,也可以把数组排序好