作用域和闭包
作用域和自由变量
自由变量
- 一个变量在当前作用域没有定义,但是被使用
- 向上一级作用域一层层依次寻找,直至找到为止
- 直到全局作用域都没找到,则报错xx is not defined
this(在函数执行时定义)
作为普通函数
function fn1(){
console.log(this)
}
fn1()
使用call apply bind
fn1.call({x: 100})
const fn2 = fn1.bind({x:200})
fn2()
作为对象方法被调用
在class方法中被调用
箭头函数
const zhangsan = {
name: '张三',
sayHi(){
console.log(this)
},
wait(){
setTimeout(function(){
console.log(this)
})
},
waitAgain(){
setTimeout(()=>{
console.log(this)
})
}
}
手写bind
bind作用
function fn1(a, b, c) {
console.log('this', this)
console.log(a, b, c)
return 'this is fn1'
}
const fn2 = fn1.bind({ x: 100 }, 10, 20, 30)
console.log(fn2())
this { x: 100 }
10 20
this is fn1
手写
Function.prototype.bindHand = function(){
const args = Array.prototype.slice.call(arguments)
const t = args.shift()
const self = this
return function(){
return self.apply(t, args)
}
}
闭包
- 一个函数和对其周围状态(词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
- 函数作为参数被传递
function print(fn){
let a = 200
fn()
}
let a = 100
function fn(){
console.log(a)
}
print(fn)
function create(){
let a = 100
return function(){
console.log(a)
}
}
let fn = create()
let a = 200
fn()
实际开发中闭包的应用
function createCache(){
const data = {}
return {
set: function(key, val){
data[key] = val
},
get: function(key){
return data[key]
}
}
}
const c = createCache()
c.set(1, 2)
console.log(c.get(1))