函数表达式理解(递归,闭包)

123 阅读2分钟

了解函数声明和函数表达式的区别?

提示:函数声明提升

函数声明

test(10) // 10
function test (count) {
    console.log(count)
}

函数表达式

test(10) // 错误
var test = function (count) { console.log(count) }
test(10) // 10

两种区别在于函数声明的方式会先读取函数声明,在执行时首先执行语句

递归

递归:函数使用自身的方法,三要素1,递归可分解 2,递归后的问题数据不一样 3,存在终止的条件

function num (count) {
	if (count === 1) {
		return 1
	} else {
		return count * arguments.callee(count - 1)
	}
}
console.log(num(4))
// 4 * 3 * 2

console.log(num(3))
// 3 * 2

解释:

从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?「从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?『从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……』」

递归子显示生活中的例子:两面平行的镜子,行程递归,相互调用自己

电影中递归的例子:《恐怖游轮》

注意:在严格模式下,argments.callee 调用函数本身

兼容严格模式

var f = (function num (count) {
    if (count === 1) {
        return 1
    } else {
        return count * num(count - 1)
    }
})
console.log(f(4))

写的有些凌乱~~,不过应该能看明白吧~

闭包

闭包就是有权访问另个函数的变量的函数(通过了解作用域链可以了解其原理)。通常创建闭包是在一个函数内创建另一个函数。

闭包缺点:总是返回最后一个变量值,因为闭包访问的不单单某个变量,而是全局变量和方法

function bibao () {
    var result = new Arrray()
    for (var i = 0; i < 5; i++) {
        re[i] = function () {
            return i
        }
    }
    return result
}

每个数组都含有一个回调函数,返回i的值,由于i是全局的,所以所以的回调中i的值最终都是10

function bibao () {
    var result = new Arrray()
    for (var i = 0; i < 5; i++) {
        re[i] = (function (num) {
            return num
        })(i)
    }
    return result
}

上述方法,解决值都一样的问题,   1,函数都是按值传参的,每执行一次,将i的值付给num,基本类型复制会产生一个变量的副本,两个变量相互独立,所以不影响值的改变,这样就产生了各自对应的数组值

this

需要了解三点

1,全局this是window

2,调用对象中函数,this是对象本身

3,函数内的函数this指向全局,可以在函数外通过将var that = this 来引用对象中this,见例子

var name = 'tank'
var obj = {
    name: 'test',
    sayName: function () {
        return function () {
            this.name
        }
    }
}
此时调用obj.sayName,返回全局name

var name = 'tank'
var obj = {
    name: 'test',
    sayName: function () {
        var that = this
        return function () {
            that.name
        }
    }
}
通过在匿名函数外部将this赋给that从而匿名函数调用对象this中的name变量