JS 面试知识学习历程(第三天) -- 作用域和闭包

Chapter3 JS基础知识(中)—作用域和闭包


这是我自己的学习过程总结,如果有什么写的不清楚的地方,欢迎大家交流、批评、提问。可以在这里评论,也可以在github上提问,谢谢大家

题目

  1. 说一下对变量提升的理解
  2. 说明this几种不同的使用场景
  3. 创建10个< a >标签,点击的时候弹出来对应的序号
  4. 如何理解作用域
  5. 实际开发中闭包的应用

知识点

  • 执行上下文
  • this
  • 作用域
  • 作用域链
  • 闭包

执行上下文

console.log(a)  //undefined
var a = 100

fn('zhangsan')  // 'zhangsan' 20
function fn(name) {
  age = 20
  console.log(name, age)
  var age
}

在一段script或者一个函数中,在第一行之前都会先生成一个执行上下文

  • 范围:一段< script >或者一个函数
  • 全局:变量定义、函数声明
  • 函数:变量定义、函数声明、this、arguments

注意: 提前的是函数声明,函数表达式只会当作变量定义提前

fn()  //不会报错
function fn () {
  //函数声明
}

//相当于 提前了 var fn1 = undefined
fn1()  // 会报错
var fn1 = function () {
  // 函数表达式
}

this

this要在执行时才会确定值,定义时无法确认

var a = {
  name: 'A',
  fn: function () {
    console.log(this.name)
  }
}
a.fn()  // this === a
a.fn.call({name: 'B'})  // this === {name: 'B'}
var fn1 = a.fn
fn1()  // this === window
  • 作为构造函数执行

    function Foo(name) {
    this = {}
    this.name = name
    return this
    }
    var f = new Foo('zhangsan')
  • 作为对象属性执行

    var obj = {
    name : 'A',
    printName: function () {
      console.log(this.name)
    }
    }
    obj.printName()  // 'A'
  • 作为普通函数执行

    function fn() {
    console.log(this)  //this === window
    }
    fn()
  • call apply bind

    // 不知道call、apply、bind语法的,先去看看语法
    function fn1(name) {
    alert(name)
    console.log(this)
    }
    fn1.call({x:100}, 'zhangsan')
    // apply和bind差不多
    var fn2 = function (name,age) {
    alert(name)
    console.log(this)
    }.bind({y:200})
    fn2('zhangsan',20)

作用域

  • 没有块级作用域

    if(true) {
    var name = 'zhangsan'
    }
    console.log(name) // 'zhangsan'
  • 只有函数和全局作用域

    var a = 100
    function fn() {
    var a = 200
    console.log('fn', a)
    }
    console.log('global', a) // 100
    fn() //200

作用域链

var a = 100
function fn() {
  var b = 200

  // 当前作用域没有定义的变量,即“自由变量”
  // 去定义!!的时候父级作用域寻找a
  console.log(a)  //100

  console.log(b) //200
}
fn()
var a = 100
function F1() {
  var b = 200
  function F2() {
    var c = 300
    console.log(a)
    console.log(b)
    console.log(c)
  }
  F2()
}
F1()  //100 200 300

闭包

function F1() {
  var a = 100

  // 返回一个函数(函数作为返回值)
  return function() {
    console.log(a)  //自由变量,父作用域寻找
  }
}
// f1 得到一个函数
var f1 = F1()
var a = 200
f1()  // 100
闭包的使用场景
  • 函数作为返回值(上一个demo)
  • 函数作为参数传递

    function F1() {
    var a = 100
    return function () {
      console.log(a)
    }
    }
    var f1 = F1()
    
    function F2(fn) {
    var a = 200
    fn()
    }
    F2(f1)  //100

解题

  1. 说一下对变量提升的理解
    • 主要就是对执行上下文的理解
    • 变量定义
    • 函数声明(注意和函数表达式的区别)
  2. 说明this几种不同的使用场景
    • 作为构造函数执行
    • 作为对象属性执行
    • 作为普通函数执行
    • call apply bind
  3. 创建10个< a >标签,点击的时候弹出来对应的序号

    // 官方写法  我自己的写法在github中的chapter1中的chapter1-04.html
    var i
    for (i = 0; i < 10; i++) {
     (function (i) {
       var a = document.createElement('a')
       a.innerHTML = i +'<br>'
       a.addEventListener('click', function (e) {
         e.preventDefault()
         alert(i)
       })
       document.body.appendChild(a)
     })(i)
    }
  4. 如何理解作用域
    • 自由变量
    • 作用域链,即自由变量的查找
    • 闭包的两个场景
  5. 实际开发中闭包的应用

    // 闭包实际应用中主要用于封装变量,收敛权限
    function isFirstLoad() {
     var _list = []
     return function (id) {
       id(_list.indexOf(id) >= 0) {
         return false
       } else {
         _list.push(id)
         return true
       }
     }
    }
    // 使用
    var firstLoad = isFirstLoad()
    firstLoad(10) //true
    firstLoad(10) //false
    firstLoad(20) //true

gitbub地址 持续更新 可下载

https://github.com/zust-hh/JavaScript_interviewing_knowledge_learning

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值