作用域和闭包
考点:this的不同场景如何取值;手写bind函数;闭包的实际开发场景,举例说明。
文章目录
一、作用域和自由变量
作用域
全局作用域
函数作用域
块级作用域
if(true){
let a = 0
}
console.log(a)//报错
自由变量
一个变量在当前作用域没有意义,但被使用了
向上级作用域,一层层依次寻找,直到被找到。
如果全局作用域中也没有找到报错,is not defined
二、闭包
函数作为参数被传递。
函数作为返回值。
function create(params) {
let a = 100
return function (params) {
console.log(a)
}
}
let fn = create()
const a = 200
fn()//100
向上级查找,不是在执行的上方查找!!!
三、this
作为普通函数
call apply bind
对象方法
class
箭头函数
this在执行的时候定义!不是在确定中使用。
function fn1 (){
console.log(this)
}
fn()//window
fn1.call({a:100}) // {a:100}
const fn2 = fn1.bind({x:200})
fn2()
//{x:200}
const zhangsan = {
name:'zhangsan',
sayHi:{
console.log(this)//当前对象
}
wait(){
setTimeout(function(){
console.log(this)//window
})
}
}
const zhangsan = {
name:'zhangsan',
sayHi:{
console.log(this)//当前对象
}
wait(){
setTimeout(()=>{
console.log(this)//当前对象
})
}
}
class People{
...
sayHai()
}
let zhangsan = new People('zhangsan')
zhangsan.sayHai()//this 是张三。
bind()
使用方法:
fn.bind(对象,值,…)
function fn1(a,b,c){
console.log('this',this) //{X:100}
console.log(a,b,c) //10,20,30
return 'this is fn1'
}
const fn2 = fn1.bind({x:100},10,20,30)
const res = fn2()
console.log(res)//this is fn1
bind来源于哪里?
Function.prototype.apply
实现原理
function fn1(a,b,c){
console.log('this',this)
console.log(a,b,c)
return 'this is fn1'
}
Function.prototype.bind1 = function(){
//参数拆解为数组
const args = Array.prototype.slice.call(arguments)
//获取this
const t = args.shift() //取出第一个
//fi.bind(fn1)
const self = this
//返回一个函数
return function(){
return self.apply(t,args)
}
}
const fn2 = fn1.bind1({x:100},10,20,30)
const res = fn2()
console.log(res)
手写apply 和 call
闭包的应用
做一个简单地cache ,数据保存
//闭包隐藏数据 提供api
function creatCache(){
let data = {} //闭包中的数据,被隐藏,不能被访问
return {
set:function(key,val){
data[key] = val
},
get:function(key){
return data[key]
}
}
}
const c = creatCache()
c.set('a',100)
console.log(c.get('a'))