1.arguments对象
[1]每个函数内部都有一个arguments对象
[2]作用是存储函数调用时传入的每一个参数(实参);
<script>
function getArg (a, b, c) {
console.log(arguments) //{0:1,1:2,length:2}
}
getArg(1, 2)
</script>
<script>
function getArg (a) {
console.log(arguments) //{0:1,1:2,length:2}
}
getArg(1, 2)
</script>
[3]arguments.callee的值是函数本身;
[4]arguments对象一般是用于在函数实参不确定的情况下使用的!
[5]案例
var length = 10
function fn () {
console.log(this.length)
}
var obj = {
method: function (fn) {
fn() // window调用---相当于window.length=10
arguments[0]() //arguments[0]等同于arguments.fn ---相当于对象调用 arguments.length=2
}
}
obj.method(fn, 1)
2.函数与外界交流
- 外部向函数内部传递数据----通过实参,形参进行传递;
- 函数内部向函数外部传递数据---通过return关键字;
- return 关键字的作用
- [1]返回数据---将函数内部的成员,返回到函数外部去,让外部去使用(成为全局变量)!
- [2]结束函数执行;
- return 关键字的作用
[1]使用retrurn返回函数内部成员(变为全局变量)的缺点--造成空间浪费
(1)在返回值为复杂数据类型的时候---每调用一次分配一次空间,若多次调用造成空间浪费的问题;
(2)举例说明
//创建一个函数
function Per() {
let per = {
name: '牛牛',
age: 23
}
return per;
}
//调用函数接收函数的返回值(对象)
let per1 = Per();
let per2 = Per();
//比较对象的值
console.log(per1 == per2); //false
- 在上面这个例子中:
- 当我们调用Per时返回一个对象分别使用per1、per2接收,但是引用地址却不相同,说明两个的数据不是存储在同一块空间;
- 局部变量在函数调用的时候被创建,在函数调用结束被销毁!
- 流程
- 1.创建Per函数--复杂数据类型,在堆区分配空间存储数据,在栈区分配空间存储数据的首地址;
- 2.系统调用函数得到函数的返回值为一个对象p1;
- 为局部变量分配空间
- 由于per为引用数据,为其在堆区分配空间,存放数据,在函数中存放堆区空间的首地址;
- return per
- 返回的是堆区空间的首地址;
- 函数执行完毕
- 局部变量内存地址被销毁,函数中存放的内存地址被销毁(但是堆区中的内容没有被销毁)
- 原因:复杂数据类型在销毁的时候销毁的是引用地址,若是在别的地方还有地址指向这个内容区域,这个内容就不会被销毁;但是若是没有内容指向这个区域,这个内容就会被销毁;
- 此时我们将per的地区地址返回作为全局变量,此时有人使用这块内容,所以不会被销毁
- 局部变量内存地址被销毁,函数中存放的内存地址被销毁(但是堆区中的内容没有被销毁)
- 为局部变量分配空间
- 3.系统调用函数得到函数的返回值为一个对象p2
- 重新为局部变量分配空间
- 由于per为引用数据,为其在堆区分配空间,存放数据,在函数中存放堆区空间的首地址;
- return per
- 返回的是堆区空间的首地址;
- 重新为局部变量分配空间
- 两个返回对象的地址不相同,所以不相等
[2]使用闭包解决return 关键字引起的空间浪费问题
- 作用:
- 可以在函数外部调用函数中的成员;
- 保证是同一个--解决了内存空间浪费的问题;
- 举例说明
<script>
//创建一个函数
function Per () {
let per = {
name: '牛牛',
age: 23
}
function cursor () {
return per
}
return cursor
}
let cursor = Per() //得到一个闭包函数
//调用函数接收函数的返回值(对象)
let per1 = cursor()
let per2 = cursor()
//比较对象的值
console.log(per1 == per2) //true
</script>
- 原因:
- 函数只执行一次,也就只生成一个per;
- 闭包函数执行多次
- 闭包函数的返回值就是我们想要数据的引用;
- 注:此处的cursor可以访问父函数(Per)的内部变量per的值,正常情况下局部变量在函数执行完毕就会被销毁,但是此处per不会销毁(因为还有人可以使用它)
- 闭包的使用步骤
- [1]在 外部函数中声明一个闭包函数;
- [2]在闭包函数中返回我们想要返回的值;
- [3]返回闭包函数;
- 使用
- [1]调用外部函数得到闭包函数;
- [2]每次想要获取返回值时调用闭包函数
- 闭包的缺点
- 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题;