当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JavaScript this指向

JavaScript this指向

2020年07月17日  | 移动技术网IT编程  | 我要评论

JavaScript this指向

一、回顾作用域
1、什么是作用域
  • 一个变量可以使用的范围
2、作用域分类
  • 全局作用域:一个 html 页面就是一个全局作用域
  • 局部作用域(私有作用域):只有函数生成私有作用域
3、作用域的上下级关系
  • 写在哪个作用域里面的私有作用域,就是哪个作用域的子级作用域

this 指向(重点)

一、定义:this 是一个使用在作用域里面的关键字
  • 作用域里面:要么写在全局,要么写在函数里面
  • 是个关键字:定义变量的时候,不能用 var this,不需要定义,直接使用就可以了
二、this 代表什么意思
  • 当你在全局作用域使用 this 的时候,this === window
    • 表示全局的意思
    • 一般很少在全局直接使用
  • 当你在函数里面使用的时候,也就是在私有作用域里面使用的时候
    • 在 JS 里面,很多的函数都会用到 this
    • 面试的时候,很多坑都是会问你 this 指向谁而出现的
三、函数内部的 this 指向(背)

在这里插入图片描述

强行改变 this 指向

  • 因为每一种函数调用方式都有自己的 this 指向
  • 强行改变:不管你本身指向哪里,我让你指哪里,你就得指向哪里
一、call( )
  • 使用方式:直接跟在函数名后面使用就可以了
调用方式 强行改变 this 指向的调用方式
fn( ) fn.call( )
obj.fn( ) obj.fn.call( )
  • 参数:call(你要改变的 this 指向, 给函数传递参数, 给函数传递参数, …)

    • 第一个参数:你要改变的 this 指向,不传递或者写一个 null 都是表示 window 的意思
    • 第二个参数开始:依次给函数传递参数
  • 作用:就是改变函数内部的 this 指向

  • 特点:直接调用函数,写完以后,函数就执行了

 	// call()
    function fn(a, b, c) {
      console.log(this) // this 指向
      console.log(a)
      console.log(b)
      console.log(c)
    }

    fn(10, 20, 30) // 标准调用 this -> window
    console.log('===============================')
    // 使用 call 改变 this 指向
    // 我准备的几个数据, 为了让你看到 this 指向确实改了
    var obj = { name: '我是 obj 对象' }
    var arr = [1, 2, 3, 4, 5]
    var num = 100
    var str = 'hello world'
    // 本次调用 fn 的时候, 把函数内部的 this 改变成了 obj
    // 100 是传递进去的第一个参数
    // 200 是传递进去的第二个参数
    fn.call(obj, 100, 200, 300) // this -> obj
    console.log('===============================')
    
    // 本次调用 fn 的时候, 把函数内部的 this 改成了 arr
    // 100 是传递进去的第一个参数
    // 200 是传递进去的第二个参数
    fn.call(arr, 100, 200, 300) // this -> arr
    console.log('===============================')
    
    // 本次调用 fn 的时候, 把函数内部的 this 改成了 num
    // 100 是传递进去的第一个参数
    // 200 是传递进去的第二个参数 
    fn.call(num, 100, 200, 300) // this -> num
    console.log('===============================')
    
    // 本次调用 fn 的时候, 把函数内部的 this 改成了 str
    // 100 是传递进去的第一个参数
    // 200 是传递进去的第二个参数
    fn.call(str, 100, 200, 300) // this -> str
    console.log('===============================')
    
    // 本次调用 fn 的时候, 把函数内部的 this 改成了 100
    // 200 是传递进去的第一个参数
    // 第二个参数没有了
    fn.call(100, 200) // this -> 100
二、apply( )
  • 使用方式:直接跟在函数名后面使用就可以了
调用方式 强行改变 this 指向的调用方式
fn( ) fn.apply( )
obj.fn( ) obj.fn.apply( )
  • 参数:apply(你要改变的 this 指向, [给函数传递参数1, 给函数传递参数2, …])
    • 第一个参数:你要改变的this 指向,不传递或者写一个 null 都是表示 window 的意思
    • 第二个参数:是一个数组或者伪数组都可以,里面的每一项依次是给函数传递参数
  • 作用
    • 改变 this 指向
    • 改变函数传递参数的方式
  • 特点:直接调用函数,写完以后,函数就执行了
 	// apply
    function fn(a, b) {
      console.log('this: ', this)
      console.log('第一个参数: ', a)
      console.log('第二个参数: ', b)
      console.log('================================')
    }

    // 准备几个数据用于改变 this 指向的时候使用
    var obj = { name: '我是 obj 对象' }
    var arr = [10, 20, 30, 40, 50]
    var reg = /^abcd$/
    var time = new Date()

    // 基础调用
    fn(10, 20)
    
    // apply 改变 this 指向
    // 本次调用 fn 的时候, 把函数内部的 this 指向改变成 obj
    // 数组中 [0] 是给 fn 函数的第一个参数
    // 数组中 [1] 是给 fn 函数的第二个参数
    fn.apply(obj, [100, 200])
    
    // 本次调用 fn 的时候, 把函数内部的 this 指向改变成 arr
    // 数组中 [0] 是给 fn 函数的第一个参数
    // 数组中 [1] 是给 fn 函数的第二个参数
    fn.apply(arr, [1000, 2000])
    
    // 本次调用 fn 的时候, 把函数内部的 this 指向改变成 reg
    // 数组中 [0] 是给 fn 函数的第一个参数
    // 数组中 [1] 是给 fn 函数的第二个参数
    fn.apply(reg, [10000, 20000])
    
    // 本次调用 fn 的时候, 把函数内部的 this 指向改变成 time
    // 数组中 [0] 是给 fn 函数的第一个参数
    // 数组中 [1] 是给 fn 函数的第二个参数
    fn.apply(time, ['hello', 'world'])
三、bind( )
  • 使用方式:直接跟在函数名后面使用就可以了
调用方式 强行改变 this 指向的调用方式
fn( ) fn.bind( )
obj.fn( ) obj.fn.bind( )
  • 参数:blind(你要改变的 this 指向, 给函数传递的参数1, 给函数传递的参数2, …)
    • 第一个参数:你要改变的 this 指向,不传递或者写一个 null 都是表示 window 的意思
    • 第二盒参数开始:依次给函数传递方式
  • 作用:
    • 改变 this 指向
    • 改变一个不需要立即执行的函数的 this 指向
  • 特点:
    • 不会直接调用函数,写完以后函数没有执行,而是返回一个新的函数,一个改变好了 this 指向的函数
    • 一个已经被改变一次 this 指向的新函数不能被再次改变
  • 例子:事件
    • div.onclick = fn —>> fn内部的 this 指向 div
    • 我想修改一下,触发点击行为的时候,不想函数里面的 this 指向 div
    • 如果写成 div.onclick = fn.call(window),点击的时候就没有函数执行了
    • 你绑定事件的时候就把函数执行了,而不是点击的时候再执行
 	// bind()
    function fn(a, b) {
      console.log('this: ', this)
      console.log('第一个参数: ', a)
      console.log('第二个参数: ', b)
      console.log('================================')
    }

    // 准备几个数据用于改变 this 指向的时候使用
    var obj = { name: '我是 obj 对象' }
    var arr = [10, 20, 30, 40, 50]
    var reg = /^abcd$/
    var time = new Date()

    // 直接调用
    fn(10, 20) // 函数调用了
    
    // 使用 bind 改变一下 this 指向
    // 本次 bind 会把 fn 函数复制一份, 把里面的 this 改变成 obj
    // 100 是给 fn 函数传递的第一个参数
    // 200 是给 fn 函数传递的第二个参数
    // 注意: 此时不会直接调用函数, 而是会有一个返回值出现
    // res 就是一个新的函数, 和 fn 函数一模一样的代码, 只是里面的 this 指向 obj
    var res = fn.bind(obj, 100, 200)
    
    // res() 就是再调用一个和 fn 一模一样的函数, 只不过 this 改变了
    res()

    // 本次 bind 回把 fn 函数复制一份, 把里面的 this 改变成 time
    var res2 = fn.bind(time, 1000, 2000)
    res2()

本文地址:https://blog.csdn.net/DingDing_Zhang/article/details/107391956

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网