作用域详解与 JS 的函数(定义, 调用, 参数, arguments, 返回值)
作用域
作用: 生效, 可以使用
域: 范围
所以说作用域指的就是一个变量可以生效的范围
作用域分类
作用域的分类可以分为两种,一种是全局作用域一种是局部或者叫私有作用域
1,全局作用域
全局作用域就是一个网站或者叫一个html文件它就是一个全局作用域打开页面的时候作用域就生成了
直到关闭页面位置
2,局部或私有作用域
函数生成私有作用域每一个函数是分别的私有作用域
例如:
function fn (){
}
这个函数fn就是一个私有作用域
作用域的上下级关系
全局作用域最大, 所有的私有作用域都是再全局作用域下面的
函数生成的私有作用域, 函数写在哪个作用域里面就是哪个作用域的子级
作用域的三大规则
作用域的三大规则
1. 变量定义规则
当你在定义一个变量的时候
你把这个变量定义在哪个作用域里面
就只有这个作用域及其后代作用域可以使用
当前作用域的所有祖先级作用域不能使用
2. 变量使用规则
当你需要使用一个变量的时候
首先, 在自己作用域内部查找, 如果有, 就直接使用, 停止查找
如果没有, 就去上一级作用域查找, 有就使用, 停止查找
如果还没有, 就再去上一级作用域查找, 有就使用, 停止查找
直到全局作用域都没有, 那么就报错 “变量 is not defined”
4. 变量赋值规则
当你需要给一个变量赋值的时候
先在自己作用域内部查找, 如果有, 就给自己作用域内部的变量赋值
如果没有, 就向上一级查找, 如果有就给父级的变量赋值
如果还没有, 就继续向上查找
直到全局作用域都没有, 那么就把这个变量定义为全局变量, 再进行赋值
清晰什么是 定义 / 使用 / 赋值 概念
1. 定义
有 var 关键字
或者 function 函数名() {}
var num // 定义变量
function fn() {} // 定义变量
2. 使用
就是当你需要拿到一个变量的值去使用的时候
console.log(num) // 我要使用 num 的值去打印出来
1 + num // 我要使用 num 的值去和 1 进行运算
var abc = num // 我要使用 num 的值赋值给 abc
3. 赋值
给一个变量进行赋值的操作
num = 100 // 要把 100 这个值赋给 num 这个变量
num = function () {} // 要把 函数 这个值赋给 num 这个变量
JS中的函数
函数是一个数据类型,
函数是一个复杂数据类型
函数的作用就是把一段功能性代码放在一个 “盒子” 里面
什么时候想用的时候, 直接把 “盒子” 里面的代码拿出来用就可以了
函数的创建
函数的创建
两种方式来创建函数
注意:
在声明函数的时候, 函数内部的代码时不会执行的
只有当你调用这个函数的时候, 里面的代码才会执行
1. 声明式函数
语法: function 名字() {}
function: 就是一个声明函数的关键字
名字: 就是你给这一段空间自定义的一个名字, 命名规则和命名规范同变量名
(): 存放参数的位置, 现在先不说, 一会详细讲, 必须写
{}: 就是你存放的一段代码
2. 赋值式函数
语法: var 名字 = function () {}
var: 定义变量的关键字
名字: 就是我们给这个函数起的一个自定义名称
=: 赋值
function: 表示一个函数
(): 写参数的位置, 必须写, 一会再说作用
{}: 存放一段代码的
定义一个函数 - 声明式
function fn() {
console.log('A')
console.log('B')
}
定义一个函数 - 赋值式
var fn = function () {
console.log('A')
console.log('B')
}
函数的调用
不管哪种方式定义的函数, 他们的调用方式是一样的
1. 直接调用(掌握)
当你定义好一个函数以后
如果你想让这个函数内部的代码执行一下
直接写 -> 函数名()
函数名: 你要让哪一个空间里面的代码执行
(): 就是调用的意思
2. 依赖行为调用(目前是了解, 后期我们要掌握)
需要给一个元素绑定一个行为
在 js 里面获取一个页面元素有一个简单的办法, 就是直接使用 id 名称
在一个页面里面, 一个元素的 id 名称可以直接被当作一个 js 的变量来使用
这个 id 名表示的就是这个元素
暂时添加一个点击行为, 就是 onclick
元素.onclick -> 表示当点击这个元素的时候
给他赋值为一个函数名称就可以了
不需要写小括号, 因为我不是让你直接执行
而是当点击的时候在执行
准备两个函数
function fn1() {
console.log('A')
console.log('B')
}
var fn2 = function () {
console.log('ABC')
}
调用函数
1. 直接调用
fn1()
直接使用函数名在括号内进行参数设定
2. 依赖行为调用
box 是页面中一个 div 的 id 名称, 在 js 里面可以直接使用
onclick 当点击在某一个元素身上的时候
等于号后面是一个函数名称, 不需要小括号
当你点击这个 box 元素的时候, 会调用后面的这一个函数
点击多少次调用多少次
box.onclick = fn2
调用时机上的区别
当你调用一个函数的时候, 方式都是一样的
但是调用的时机, 取决于你使用哪种方式定义函数
声明式函数(function fn() {})
可以在声明之前调用, 也可以在声明之后调用
赋值式函数(var fn = function () {})
只能在声明之后调用, 声明之前调用会报错
函数的参数
函数里面的参数分成两种
1. 形参
就是写在函数定义时候的 () 里面的
可以写多个, 多个的时候中间用 逗号(,) 分隔
就是一个只能在函数内部使用的变量
至于这个变量(形参) 的值是什么, 由函数的实参决定
2. 实参
就是写在函数调用的时候的 () 里面的
可以写多个, 多个之间使用 逗号(,) 分隔
是一个准确的数据
用来给对应的形参赋值的
function fn(a, b, c) {
console.log(a)
console.log(b)
console.log(c)
}
fn('字符串',123,true)
这时打印出来的数据是: 字符串(字符串),数字(123),布尔值(true)
函数参数的个数关系
1. 形参和实参一样多
按照从左到右的顺序一一进行赋值
2. 形参比实参多
前面的一一对应的关系, 多出来的形参, 没有实参进行赋值
在函数内部使用的时候, 就是一个没有赋值的变量, 就是 undefined
3. 实参比形参多
前面的一一对应的关系, 多出来的实参, 在函数内部没有形参接收
相当于你白写了多出来的实参, 在函数内部不能直接使用
函数内部的一个特殊的变量, arguments
函数内部的一个特殊的变量, arguments
在每一个函数内部, 都有一个天生的变量
不需要我们取定义, 直接就能拿来使用
这个变量叫做 arguments
表示所有实参的集合
详解 arguments
会把所有的实参按照从左到右的顺序依次排好
给每一个实参一个编号(索引 / 下标)
这个编号(索引 / 下标) 是从 0 开始的, 依次递增
当你需要获取到这里面的某一个的时候
你只要写 arguments[编号] 就能得到某一个准确的值
arguments 还有一个属性叫做 length
表示 arguments 这个集合的长度, 也就是里面有多少个数据
值是一个 number 数据类型的数字
如果你想得到这个属性就写 arguments.length
使用循环遍历整个 arguments 获取到每一个数据
因为 arguments 的索引(下标) 是按照从 0 开始依次叠加的顺序
我们的循环刚好也可以给我提供一组有规律的数字
所以我们可以使用循环的方式来遍历 arguments
循环遍历的时候为什么要小于 length
当 length === 5 的时候, 我们要的索引数字是 0 1 2 3 4
for (var i = 0; i < 5; i++) {} 得到的 i 分别时 0 1 2 3 4
当 length === 7 的时候, 我们要的索引数字是 0 1 2 3 4 5 6
for (var i = 0; i < 7; i++) {} 得到的 i 分别是 0 1 2 3 4 5 6
什么时候使用 arguments 什么时候使用形参
因为函数是我们提前定义好的, 为了更好的书写代码, 为了以后多次调用
当我们定义函数的时候, 我就能确定以后我使用的时候的实参的个数
我们推荐使用形参的方式来获取, 因为方便
当我们定义函数的时候, 我不能确定以后我使用的时候的实参的个数
我们推荐使用 arguments 的形式来获取, 因为灵活
函数的返回值
函数的返回值
什么是返回值: 也就是一个函数的结果
例子: parseInt()
parseInt 是一个 js 内置(自带) 的一个函数
parseInt() 就是在调用这个函数
parseInt(10.234) 就是传递的一个参数
var result = parseInt(10.234)
result 接收的就是 parseInt 这个函数的返回值
这个函数里面做的是 把你传递进来的数据转换成数值类型
然后再返回给你
再函数里面添加返回值使用 return 关键字
return 就是再函数里面使用的
你想让这个函数返回什么, 就写 return 你要返回的数据
设置时间
设置时间对象的指定内容
我单独只设置时间对象里面的某一个信息
1. setFullYear()
作用: 设置时间对象的年份信息
语法: 时间对象.setFullYear(你要设置的年份)
2. setMonth()
作用: 设置时间对象的月份信息(0 表示 1 月, 11 表示 12 月)
语法: 时间对象.setMonth(你要设置的月份)
3. setDate()
作用: 设置时间对象的日期信息
语法: 时间对象.setDate(你要设置的日期)
4. setHours()
作用: 设置时间对象的小时信息
语法: 时间对象.setHours(你要设置的小时)
5. setMinutes()
作用: 设置时间对象的分钟信息
语法: 时间对象.setMinutes(你要设置的分钟)
6. setSeconds()
作用: 设置时间对象的秒钟信息
语法: 时间对象.setSeconds(你要设置的秒钟)
7. setTime()
作用: 通过时间戳直接设置一个时间对象
语法: 时间对象.setTime(时间戳)