JS基础-作用域和闭包

1、什么是作用域?什么是自由变量?

1.1、作用域有分为三种

1、函数作用域
2、块级作用域

  • if(true){let x = 100};
  • console.log(x)
  • //会报错,因为用了let,用const也是会报错

3、全局作用域
作用域图示在这里插入图片描述
1.2、自由变量

  1. 当一个变量在当前作用域使用了,但是没定义
  2. 会在自己的上一级作用域找
  3. 最后没找到就是xx is undefined

2、什么是闭包,闭包在哪里被使用?

闭包的好文章

闭包一般只有两种形式的使用

  • 函数作为返回值*(例1)*
  • 函数作为参数*(例2)*
//例1
function a(){
    let num  = 100;
    return function b(){
        console.log(num)
    }
}
let num = 200;
let ok = a()
ok()//100
//第二张补充写法:有注意点
function a(){
    let num  = 100;
    let res = function b(){
        console.log(num)
    }
    num++;
    //因为在return之前有了num++所以函数b在找num时会在return之前运算num
    return res
}
let num = 200;
let ok = a()
ok()//100
//例2
function a(fn){
    let num = 200;
    fn()
}
let num = 100;
function fn(){
    console.log(num)
}
a(fn)//100

所有自由变量的查找,不是在函数调用的地方找,而是在函数声明的地方向上查找

3、this 有几种赋值情况

this的好文章
3.1、this的指向

this的值是在函数调用的时候确定的

  • 普通函数的this指向Window
  • 箭头函数的this指向他的上一级
  • 定时器那些的this指向window
  • 一个构造函数里面的this指向这个实例对象*(例3)*
  • 一个class的this指向这个实例对象*(例4)*
//例3
function a(){
    this.kk =100
    console.log(this)
}
let b = new a()
//{kk: 100}
//例4
class A {
    constructor(){
        this.a = 99
    }
    speak(){
        console.log(this)
    }
}
let b = new A()
b.speak()
//{a:99}

3.2、改变this的指向(3种办法)

  • bind()
  • call()
  • apply()

这三个方法都在Function.prototype上

//...args是吧参数展开
function a(...args){
    console.log(...args)
    console.log(this)
}
let b = {}
a(1,2)//指向window,
a.call(b,1,2)//call可以改变this的指向为b,但是,参数必须一个一个写
a.apply(b,[1,2])//apply也可以改变this的指向为b,但是,他的参数要写在数组里
a.bind(b,1,2)()//bind的是es5新增的,有兼容性问题,而且,他不会立即执行,只会返回一个函数。这里在后面加了()是让他立即执行

4、作用域相关面试题

1、闭包的使用场景

传入一个函数或者返回一个函数

2、this的问题

this的值是在函数调用的时候确定的

  • 普通函数里面的this指向Windows
  • 箭头函数里面的this指向上一级
  • 用call,apply,bind改变this的指向
  • 定时器里面的this指向window
  • 构造函数里面的this和class里面的this指向实例对象

3、手写一个bind函数

function a(...args){
    console.log(...args)
    console.log(this)
}
let b = {}
Function.prototype.bind1 = function(){
	//这里的arguments是不是数组,所以这样操作,吧函数的参数放进数组
    const arr = Array.prototype.slice.call(arguments)
    //取出数组第一项
    const first = arr.shift()
    //这里的this就是函数a
    const self  = this
    return function(){
    //这里的this是window
        return self.apply(first,arr)
    }
}
a.bind1(b,1,2)()

5、实际开发中闭包的应用

可以隐藏数据,也可以防止数据被污染

手写一个cache的工具

//这样的话只露出两个api,别人就操作不了data了
function cache(){
    let data = {}
    return {
        set(key,value){
            data[key] = value
        },
        get(key){
            return data[key]
        }
    }
}
const h = cache()
h.set('jj',1000)
console.log(h.get('jj'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值