1.关于函数的参数
- 函数的参数在函数内部表现为一个数组(这个数组并不是Array的实例,但是具有数组特性),故而函数不关心传入参数的个数和参数的类型(所以不能重载),并且只要是用function关键字定义的函数(箭头函数除外),都可以在其内部访问到arguments对象。值得注意的是:
1.参数使用可以既使用命名参数,也能使用arguments,虽然命名参数和arguments存在对应关系,如:num1与arguments[0]相对应,此时如果修改num1那么arguments[0]的值也会变,但是这并不意味着两者的地址一样,只不过保持同步更新而已。
2.若只传入了一个参数,那么即使这个时候给arguments[1]赋值,也不会反映到第二个参数上。因为arguments的长度由实际传入参数的个数决定的,而不是由定义函数时所给的参数个数决定的。
3.在严格模式下重写arguments对象会报错,并且始终以传入的参数值为准,修改了命名参数也不会反映到arguments上。
4.使用默认参数时,arguments的值始终与传入的参数值保持一致,即使最后修改了,不管是修改命名参数还是arguments,二者此时并并不保持同步。如:
5.虽然箭头函数没有arguments,但是可以用一个函数将其包装在内,如:
2.函数的声明与函数表达式
区别:js引擎在读取任何代码时。会先读取函数的声明,然后在执行上下文生成函数定义,而函数表达式是只有执行到那一行才会在执行上下文生成对应的函数定义。且函数声明存在作用域的提升。故而函数声明可以在函数之前调用,函数表达式不行。
3.函数内部(两个特殊对象:this和arguments)
1.argument
(除开上面讲函数参数是提到的)
- callee属性:指向arguments对象的一个函数。通过它可以让函数逻辑和函数名解耦,即使有一天函数名(函数名是对函数的引用)被赋值到别处通过arguments.callee就可以正确调用。
- caller:引用的是调用当前函数的函数。
2.new.target:检测函数是否使用new关键字调用。
4.闭包
-
闭包是指那些引用外层作用域的变量的函数,闭包对外层作用域的引用是通过作用域链实现的。
-
用处:1.可以访问函数内部的变量。2.可以把变量存储在内存里。
-
弊端:容易造成内存不能及时得到释放。因为内层作用域要访问到外层作用域,就要引用外层作用域,而当整个外层函数执行完毕,按理来说,其执行上下文和活动对象都应该被销毁,但是由于闭包的存在(内层函数对外层函数的引用),就导致了外层函数的执行上下文被销毁而活动对象不被销毁,该被释放的内存未得到释放,只有当内层函数被销毁了内存才会被释放。