JavaScript中This的三种指向以及上下文调用,闭包,递归详解

目录

函数的三种调用方式(this指向)

函数执行的上下文模式

 Call()

apply()

bind()

递归

递归函数介绍

闭包(closure)

闭包的定义

闭包的作用

闭包小结


函数的三种调用方式(this指向)

复习函数三种调用方式:普通函数 对象方法 构造函数

  • 重点:理解this关键字作用:谁调用这个函数,this指向谁

  • 函数三种执行模式 : 全局函数 、 对象方法 、 构造函数
                this : 谁 `调用` 我,我就指向谁
                1. 全局函数 : this指向window
                2. 对象方法 : this指向对象
                3. 构造函数 : this指向new创建的空对象

 <script>
    /**1.this环境对象,谁调用我就指向谁 
    重点:函数与声明无关 取决于函数调用
    1 普通函数调用, 函数名()   this指向window
    2 对象方法调用  对象名.方法名()   this指向对象
    3 构造函数调用   new 函数名()     this指向new创建的实例对象
      2.分析this指向心得,this指向取决于函数的调用 而函数有三种调用方式 所以this指向也会有三种方式
    1 优先用排除法分析,如果有new关键字 则指向nwe创建对象 否则不是window就是对象
    2 如果判断this是window还是对象,就看调用是函数名()还是对象名.方法名()
    */
  </script>

函数执行的上下文模式

call() apply() bind()

异同点

  • 相同之处:都可以修改函数中this指向

  • 不同点:传参方式不同

    • call()语法: 函数名.call(this修改后的指向,arg1,arg2…………)

    • apply()语法:函数名.apply(this修改之后的指向,伪数组或者数组)

      • bind()语法:函数名.bind(this修改后的指向,arg1,arg2....)

      • bind()语法并不会立即执行函数,而是返回一个修改指向后的新函数,常用于回调函数

 Call()

<script>
    /**1.this环境对象,谁调用我就指向谁 
    重点:函数与声明无关 取决于函数调用
    1 普通函数调用, 函数名()   this指向window
    2 对象方法调用  对象名.方法名()   this指向对象
    3 构造函数调用   new 函数名()     this指向new创建的实例对象
      2.分析this指向心得,this指向取决于函数的调用 而函数有三种调用方式 所以this指向也会有三种方式
    1 优先用排除法分析,如果有new关键字 则指向nwe创建对象 否则不是window就是对象
    2 如果判断this是window还是对象,就看调用是函数名()还是对象名.方法名()
    */

    /**
     1.默认情况下.   this指向是无法修改的
     *  1 普通函数调用, 函数名()   this指向window
        2 对象方法调用  对象名.方法名()   this指向对象
        3 构造函数调用   new 函数名()     this指向new创建的实例对象
    2.上下文调用:   修改函数中this指向
    (1)函数名.call(修改的this,参数 1,参数2.....)
    (2) 函数名.apply()
  (3)函数名.bind(修改的this)
        *bind不会立即调用函数,而是得到一个修改后的新函数
    经典面试题,请说说call,apply,bind有什么区别
    */
    function fn(a, b) {
      console.log(this)
      console.log(a, b)
    }
    fn(1, 2) //  这个this指向window

    fn.call({
      name: '聪明蛋'
    }, 10, 20)
    //函数名.call(修改的this,参数 1,参数2.....)
    // call 场景 : 数据类型检测

    //1.typeof 数据 :检测数据类型
    /**
     * typeof 有两种数据类型无法检测:null.array  都会得到object
     */
    console.log(typeof 123) // number
    console.log(typeof '123') // string
    console.log(typeof true) //boolean
    console.log(typeof false) //boolean
    console.log(typeof undefined) //undefined
    console.log(typeof null) //object
    console.log(typeof [10, 20, 30]) //object
    console.log(typeof
      function () {}) //function
    console.log(typeof {
      name: '聪明蛋'
    }) //object

    // 2.object.prototype.toString():得到固定格式字符串
    // "[object.type]",其中的type 是对象
    // 检测数据类型固定语法:object.prototype.toString.call(数据)
    console.log(object.prototype.toString.call(123)) //[object Number]
    console.log(object.prototype.toString.call('123')) //[object String]
    console.log(object.prototype.toString.call(true)) //[object Boolean]
    console.log(object.prototype.toString.call(undefined)) //[object Undefined]
    console.log(object.prototype.toString.call(null)) //[object Null]
    console.log(object.prototype.toString.call([12, 123, 123, ])) //[object Array]
    console.log(object.prototype.toString.call(function () {})) // [object Function]
    console.log(object.prototype.toString.call({
      name: '聪明蛋'
    })) // [object Object]
  </script>

apply()

  function fn(a, b) {
      console.log(this)
      console.log(a, b)
    }
    //call传参需要一个一个传,一般用于修改单个参数的函数this
    fn.call({
      name: '张三'
    }, 10, 20)
    //apply传参通过数组来传.一般用于修改多个参数的函数this
    fn.apply({
      name: '李四'
    }, [30, 40])

bind()

 function fn(a, b) {
      console.log(this)
      console.log(a, b)
    }
    //call传参需要一个一个传,一般用于修改单个参数的函数this
    fn.call({
      name: '张三'
    }, 10, 20)
    //apply传参通过数组来传.一般用于修改多个参数的函数this
    fn.apply({
      name: '李四'
    }, [30, 40])
    // bind不会立即调用函数,而是得到一个修改后的新函数
    fn.bind({
      name: '王五'
    })

递归

递归函数介绍

  • 1.递归函数:一个函数自己调用自己

  • 2.递归函数特点

    • a.一定要有结束条件,否则会导致死循环

    • b.能用递归函数实现的需求,就一定可以用循环调用函数来解决,只是代码简洁与性能不同而已

<script>
    let num = 1
    while(num<=3){
      console.log('聪明蛋最好看')
      num++
    }
    
    let i = 1
    function fn() {
      if (i <= 3) {

        console.log('聪明蛋最漂亮')
        i++
        fn()
      }
    }
    fn()
  </script>

闭包(closure)

闭包的定义

  • 1.闭包 : 是一个可以访问其他函数作用域的函数

    • 2.闭包 = 函数 + 上下文的引用,闭包不等于函数。以下代码就构成了闭包:

闭包的作用

直接作用:解决变量污染问题,让变量被函数保护起来

闭包小结

  1. 闭包 = 函数 + 上下文的引用

  2. 闭包的作用:解决变量污染问题,让变量被函数保护起来。

    • 在 ES5 时代,闭包可以解决一些其他 JavaScript 的小 BUG,但随着 ES6 let 等新语法的诞生,之前一些闭包的使用场景已经不再需要,后续在就业课中会讲,帮助大家突击面试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值