闭包是什么?
定义在函数内部的函数 拿到函数内部的变量?
闭包就是能够读取其他函数内部的函数?
function f1() {
var a = 10
function f2() {
console.log(a)
}
f2()
}
f1()
全局变量存在window上,一直存在,局部变量是在函数作用域的时候存在。
为什么需要闭包?
局部变量是有生命周期的,局部变量无法共享和长久保存,而全局变量可能造成变量污染,当我们希望有一种机制既可以长久保存变量又不会造成全局污染。
闭包的写法:
//闭包特性:返回的是一个函数,并且这个函数对局部变量存在引用,这就形成包含关系,他是可以维持一个变量的存在
function f1() {
var a = 10
function f2() {
a++
console.log(a)
}
return f2
}
var f = f1() //f1()执行的结果就是闭包
f()
//简化写法
function f1() {
var a = 10
return function () {
a++
console.log(a)
}
}
var f = f1()
f()
//例子 两个人行走(a,b) 需要有一个状态来存储行走的距离
#利用一个变量给很多个人使用
function f1() {
var a = 0
return function() {
a++
console.log(a)
}
}
var a = f1()
var b = f1()
image.png
总结:闭包返回的是一个函数,并且这个函数对局部变量存在引用,这就形成了包含关系,他是可以维持一个变量的存在,最常用的场景是接口请求的封装
二、this指向
window.onload = function() {
//经典面试题
var length = 88 //定义变量
function test() { //定义test()
console.log(this.length)
}
var obj = { //定义obj对象
length = 99
action:function(test) {
test() //88 没有调用者 默认指向window
//arguments[0]()等同于 arguments.test()
arguments[0]() //2 this 指向arguments => this.length=>arguments.length
}
}
obj.action(test,[1,2,3]) //执行obj.action()
}
//答案:88 2
//考核点:this指向
//this指向规则:运行一个函数,有没有调用者
//1、没有调用者,默认指向全局,即window(严格模式下是undefined)
//2、有调用者,指向的就是当前调用者
var length = 88 //定义变量
function test() { //定义test()
console.log(this.length) //this.length => window.length
}
test() //88 没有调用者,默认指向全局,即window
var length = 88 //定义变量
function test() { //定义test()
console.log(this.length) //this.length => obj.length
}
var obj = { //定义obj对象
length = 99
action:test
}
//obj.action()//99 有调用者,调用者obj
var f = obj.action
f()//没有调用者 this.lenght => window.length
// 扩展题
var length = 88 //定义变量
function test() { //定义test()
console.log(this.length) //this.length => arr.length
}
var arr = [test,2,3,4]
arr[0]() //4 arr[0]() =>test() 相当于arr.test() 调用者是arr
//arguments 所有参数集合 类似数组
function f() {
console.log(arguments[0]);
console.log(arguments.length);
}
f(1,2,3,4)
没有调用者 this指向window 有调用者this指向调用者
三、作用域
局部变量vs全局变量
1、声明位置不一样:全局变量定义在函数体外面,局部变量定义在函数体里面
2、作用域不同:全局变量作用域是整个程序,局部变量作用域仅限于函数体内部
3、生存期不同 :局部变量用完就删除了,全局变量页面不关闭就不会被删除
块级作用域:js没有块级作用域,函数除外
隐士全局变量VS全局变量
var a = 1 //定义全局变量
a = 1 //定义隐士全集变量 可以被delete(a)
全局变量不能被删除,隐士全局变量可以被删除
四、递归
函数在运行时调用自己的情况,叫做递归
只递不归会导致程序崩溃 (栈溢出)
为了避免崩溃,递归函数中一定要包括条件语句,在合适的时候终止递归
网友评论