函数声明和函数表达式的区别
使用函数声明的方法定义函数时,会有变量提升,但是函数表达式则不会;
使用函数表达式来实现递归:
function factorial(num) {
if(num <= 1) {
return 1
} else {
// arguments.callee 总是指向调用参数的函数本身
return num * arguments.callee(num - 1)
}
}
var result = factorial(4)
alert(result)
//将factorial 赋值给factorial2后,再设置factirial为null,再调用函数会
//报错,因为函数内部还是会使用到factorial 方法,此时已经时null
var factorial2 = factorial
factorial = null
alert(factorial2(3))
//还可以使用命名函数表达式的方法
var jiecheng = (function f(num){
if (num <= 1) {
return 1
} else {
return num * f(num - 1)
}
});
var jiecheng2 = jiecheng;
jiecheng = null;
alert(jiecheng2(4))
闭包:
有权访问另一个函数作用域中变量的函数
// 理解闭包,使用第五章中提到的比较大小的函数作为例子
//该函数返回一个匿名函数作为结果
function creatCompareFunction(propertyName) {
//该匿名函数即为闭包
return function compare(value1, value2) {
var value1 = value1[propertyName]
var value2 = value2[propertyName]
if (value1 < value2) {
return -1
} else if (value1 > value2) {
return 1
} else {
return 0
}
}
}
var compare = creatCompareFunction('name')
//n排序在g后面,因此 n > g
var result = compare({name: 'nicholas'}, {name: 'gregy'})
console.log(result); // 1
闭包和变量:
闭包只能取得外部函数中任何变量的最后一个值。
// 闭包与变量
function createFunction() {
var result = new Array();
for (var i = 0; i < 10; i++) {
result[i] = function() {
return i
}
}
return result
}
//返回一个函数数组,有10个闭包函数,但是其中的 i 都是10
console.log(createFunction());
//在闭包内再添加一次匿名函数可以使得每个闭包函数内的i值按索引号变化
function createFunction1 () {
var result = new Array()
for (var i = 0; i < 10; i++) {
result[i] = function(num) {
return function() {
return num
}
}(i) //将索引号 i 值作为参数传递给num
}
return result
}
console.log(createFunction1());
闭包中的this指向会导致一些问题。匿名函数具有全局作用域,因此匿名函数内部的this指向window,而不是其外部函数的作用域。使用的时候需要格外注意。
模仿块级作用域
ES6之前没有块级作用域, 可以使用匿名函数来模仿块级作用域,使用方法如下:
//模仿块级作用域
function fun1() {
for (var i = 0; i < 10; i++) {
// alert(i)
console.log(i); //0, 1, 2, 3, 4, 5, 6,----9
}
// alert(i)
console.log(i); //10
}
// fun1()
function fun2() {
(function() {
for (var i = 0; i < 10; i++) {
console.log(i);
}
})() //i为块级作用域(实际上是函数内部作用域)中定义的变量,使用完及销毁
console.log(i); // i is undefined 会报错
}
fun2()
有关块级作用域,模块模式等之后在ES6中都有更新,因此此处粗略过一遍即可。