JavaScript中的函数学习
1、函数的定义
function funName(){函数体语句}
var fun = function(){函数体语句}
,匿名函数(函数表达式),不允许提升。
fun() // 'B' -- 函数定义优先提升
var fun = function(){
console.log('A')
}
function fun(){
console.log('B')
}
func() // 'A'
2、arguments
类数组对象
- 函数内的
arguments
表示实参的列表 - 拥有
length
属性,以及可以通过下标访问。但不能调用数组的方法
function fun(){
console.log(arguments) // [1,2,3,4,5]
console.log(arguments.length) // 5
console.log(arguments[0]) // 1
}
fun(1,2,3,4,5)
3、递归
- 函数自己调用自己,直到执行某一次时不再调用自身(边界条件),函数被一层一层返回,故称函数递归。
// 阶乘
function fun(n) {
return n==1 ? 1 : n * fun(n-1);
}
var a = fun(4)
console.log(a) // 24
数组的深拷贝
var arr = [1,2,3,[4,5,[6,7]]]
function fun(n){
var res = []
for (var i = 0; i < n.length;i++){
if (Array.isArray(n[i])){
res.push(fun(n[i]))
}else{
res.push(n[i])
}
}
return res
}
var a =fun(arr)
a.push(8)
console.log(arr) // [1,2,3,[4,5,[6,7]]]
console.log(a) // [1,2,3,[4,5,[6,7]],8]
4、全局变量与局部变量
- 局部变量:定义在函数内的变量
- 全局变量:定义在函数外的变量
4.1、遮蔽效应
- 全局变量与函数内的局部变量同名,局部变量会将全局变量遮蔽
var a = 10
var f = function(){
var a = 5
a++
console.log(a) // 6
}()
console.log(a) // 10
var的变量声明提升与遮蔽效应的案例
- var变量声明提升,只提升声明,不提升值。
var a = 10
var f = function(){
a++
var a = 5
console.log(a) // 5
}()
console.log(a) // 10
4.2、形参也是局部变量
var a = 10
var f = function(a){
a++
console.log(a) // 6
}(5)
console.log(a) // 10
4.3、作用域链
- 在函数嵌套中,变量会向上层寻找它的定义
var a = 10
var b = 20
var f = function(){
var c = 30
var i = function(){
var a = 40
var d = 50
console.log(a,b,c,d) // 40 20 30 50
}()
}()
4.4、不加var将定义全局变量(很傻不要用,会被打断狗腿)
var f = function(){
a = 3
}()
console.log(a) // 3
5、闭包
闭包 = 函数 + 变量
- 闭包是函数与该函数声明时所处的环境状态(一般指变量)的组合。
function fun(){
// 变量a和函数f组成了闭包
var a = 5
return function(){
console.log(a)
}
}
var fun1 = fun()
fun1() // 5
闭包的特性
记忆性
:当fun()函数
被调用后,变量a并不会被释放,始终保存在内存中。模拟私有变量
闭包面试题
- 闭包的实例的相互独立的
- 同一闭包实例对内部变量修改是记录的
function addCount(){
var count = 0
return function(){
count += 1
console.log(count)
}
}
var fun1 = addCount()
var fun2 = addCount()
// 闭包的实例的相互独立的
fun1() // 1
fun2() // 1
// 同一闭包实例对内部变量修改是记录的
fun2() // 2
fun1() // 2