JS的学习理解--->函数

312 阅读6分钟

函数 封装功能块

函数定义:
函数声明
function f(参数1){ } function用来声明函数 f为函数名 ()是函数的特殊标志 函数表达式(相当于变量)
函数调用:
如果定义好一个函数,需要调用它,他才会执行函数体中的代码,若不调用,就相当于没有定义该函数。
函数的参数:
形参:
函数定义时,()中写的参数,叫形参,相当于函数内部的局部变量,作用是用来接收实参。
function f(a,b){....}
实参:
函数调用时,()中写的参数,叫实参,作用是给函数传递真实的数据,形参接收。
函数的返回值:
通过return返回,返回到函数的调用处。函数体中return后面的语句不会再执行。return也叫作跳转语句。
命名法:
小驼峰命名法:toString()
大驼峰命名法:ToString()
下划线命名法:to_String()
作用域:
全局作用域
局部作用域:函数内部会形成一个局部作用域(函数作用域)
块级作用域(let{})
参数的传递:
基本的数据类型传递(值传递)
把栈区的数据copy一份给了形参,形参和实参是个自独立一个内存空间。
改变形参,对实参没有影响。
引用数据类型的数据(引用传递)
就是把栈区的地址copy了一份给形参,形参和实参同时指向堆区同一片内存空间。
通过形参改变堆区内存空间的数据,实参这个地址对应的数据也会发生改变。
函数可以作为另一个函数的参数:
一个函数可以作为另一个函数的参数,这个函数可以是函数声明也可以是函数表达式。
在JS,我们可以把一个函数声明,作为别一个函数的参数
arguments:
函数调用过程就是实参向形参赋值的过程。实参会复制一份给形参。
除了复制给形参一份,他还会给arguments一份。
arguments中收集了实参。
arguments只是函数内部的属性,在函数外不能访问
arguments和形参之间一一对应:
当形参改变了,arguments里面的值也会改变
当改变了arguments里面的数据,形参也会发生改变
什么时候使用形参,什么时候使用arguments?
1,当实参非常多时,写一堆的形参来接收,不方便,此时你就可以使用arguments
2,当实参有特殊含义时,需要有一个特殊的标识,就可以使用形参来标识
JS有两个容器:
数组:[1,2,3,"hello",true] 获取某个元素时,使用索引
对象:{name:"zhangsan",age:100} name和age加Key zhangsan和100叫value
函数返回多个值:
默认情况下,Js函数只能返回一个值。
如果你想返回多个值的话,那么你可以使用容器。
总结:
1. 函数的作用: 封装成功能块,用的时候直接调用
2. 函数的定义: 函数声明 函数表达式
3. 函数的调用: 函数定义完后,没有调用,相当于没有写 函数调用的过程就是实参向形参赋值的过程
4. 函数的返回值: return 如果没有写返回值,默认返回undefined
5. 函数的参数: 形参(函数定义是()里面的参数)和实参(函数调用时()里面的参数)
6. 参数的传递: 值传递,引用传递
7. 函数可以作为另一个函数的参数 setTimeout(function() {},3000)
8. arguments 收集实参
9. 返回时想返回多个值时,需要返回一个容器


ES6中对函数的扩展

参数的默认值:
1. 参数默认值 当我们没有给形参传值时,使用默认值,如果给形参传值,使用我们传递的值。
2. 传递赋值时,实参的第一个会赋给形参的第一个,依次向后
3. 如果实参个数多于实参,后面的实参就忽略了
4. 如果形参个数多于实参个数,后面的形参的值是undefined
rest参数:
格式:在函数定义时的形参的位置写的 ...rest (rest只是参数名,可以改变)
作用:当传递的实参个数较多时,接收多余的实参

箭头函数:
原型:function f(){...} ---------->let f = ()=>{...}省略了function
特点1:只有一个形参时,()可不写

enter description here
特点2:只有一个带return语句 {} 和 return 都可以不写
enter description here
特点3:只有一个不带return语句 {} 可以不写
特点4:如果返回对象,把{} 和 return 省掉的话,需要给这个对象加()
enter description here
在箭头函数中没有arguments,可以使用rest参数
在箭头函数中没有this
------------------ 执行上下文
局部代码:在函数里面的代码叫局部代码。
全局代码:默认进入的就是全局代码

全局执行上下文,函数局部代码:
当执行全局代码时,产生一个全局执行上下文。
全局执行上下文只有一个。
当执行函数代码时,产生一个函数执行上下文。
每调用一次函数,都会产生一个函数的执行上下文件。函数执行上下文可以有N个。

enter description here
执行上下文栈:
全局执行上下文位于栈底,当调用一个函数,就产生一个局部地执行上下文,这个局部地执行上下文 要压栈,当这个函数执行完,这个执行上下文就要出栈。
执行上下文的作用:
给全局代码或局部代码提供数据。数据包含变量和函数。
全局执行上下文中组成: 全局地变量和函数
局部执行上下文中组成: 本函数内部的变量,arguments,内部定义的函数,父级函数的执行上下文

为什么函数内部的变量,在函数的外部无法访问,从执行上下文的角度来分析:

enter description here

作用域链:
作用域链是一种数据查找机制,弄清楚作用域链,需要先知道执行上下文。
将函数定义到另一个函数内部:
某些函数,不想让别人直接访问,就可以把这个函数定义到另一个函数的内部,达到封装效果。
函数可以作为返回值:
函数在js中也是一种数据类型,引用数据类型。引用数据类型:[] {} 函数
立即执行的函数表达式IIFE:
不需要我们手动地调用就可以执行的函数。
实现:()把整体包起来 ()把函数声明包起来 + - * / !
IIFE最好在最后面加上分号;
闭包:
如果一个函数中,又嵌套了一个函数,并且这个函数引用外面函数的变量
当一个函数使用完毕后,它里面的变量所占的空间会被释放
闭包可以延长变量的生命周期
闭包会产生内存泄漏