this关键字

Mr.ZhaoAbout 3 min

每一个函数内部都有一个关键字是 this ,this用于访问当前方法的所属对象,可以让我们直接使用的

重点: 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系

1. this指向

函数内部的 this 指向谁,取决于函数的调用方式(取决于函数被谁调用)

  • 全局定义的函数直接调用,this => window

  • 普通函数没有明确调用者时 this 值为 window,严格模式下没有调用者时 this 的值为 undefined

    function fn() {
      console.log(this)
    }
    fn()
    // 此时 this 指向 window
    
  • 对象内部的方法调用,this => 调用者

    var obj = {
      fn: function () {
        console.log(this)
      }
    }
    obj.fn()
    // 此时 this 指向 obj
    
    var obj = {
    
    }
    obj.fn = function () {
        console.log(this)
      }
    obj.fn()
    // 此时 this 指向 obj
    
  • 定时器的处理函数,this => window

    setTimeout(function () {
      console.log(this)
    }, 0)
    // 此时定时器处理函数里面的 this 指向 window
    
  • 事件处理函数,this => 事件源

    div.onclick = function () {
      console.log(this)
    }
    // 当你点击 div 的时候,this 指向 div
    
  • 自调用函数(立即执行函数),this => window

    (function () {
      console.log(this)
    })()
    // 此时 this 指向 window
    

2. call 和 apply 和 bind

刚才我们说过的都是函数的基本调用方式里面的 this 指向,我们还有三个可以忽略函数本身的 this 指向转而指向别的地方,这三个方法就是 callapplybind,它们是强行改变 this 指向的方法

2.1 call

call 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

语法: 函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)

var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.call(obj, 1, 2)

fn() 的时候,函数内部的 this 指向 window,fn.call(obj, 1, 2) 的时候,函数内部的 this 就指向了 obj 这个对象,使用 call 方法的时候会立即执行函数,第一个参数是你要改变的函数内部的 this 指向,第二个参数开始,依次是向函数传递参数

2.2 apply

apply 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向

语法: 函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...])

var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.call(obj, [1, 2])

fn() 的时候,函数内部的 this 指向 window,fn.apply(obj, [1, 2]) 的时候,函数内部的 this 就指向了 obj 这个对象,使用 apply 方法的时候,会立即执行函数,第一个参数是你要改变的函数内部的 this 指向,第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数

2.3 bind

bind 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向,和 call、apply 有一些不一样,就是不会立即执行函数,而是返回一个已经改变了 this 指向的函数

语法: var newFn = 函数名.bind(要改变的 this 指向); newFn(传递参数)

var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
var newFn = fn.bind(obj)
newFn(1, 2)

bind 调用的时候,不会执行 fn 这个函数,而是返回一个新的函数,这个新的函数就是一个改变了 this 指向以后的 fn 函数,fn(1, 2) 的时候 this 指向 window,newFn(1, 2) 的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj