函数this三种指向及上下文调用

202 阅读2分钟

this三种指向

今天谈谈环境对象this,下面给大家介绍一下this在普通函数,构造函数,对象方法三种环境下的默认值

重点: 环境对象 this : 谁‘调用’我,我就指向谁 (this指向取决于函数调用, 与声明无关 )

普通函数: 函数名()   this 指向 window
对象方法: 对象名.方法名()   this 指向 对象
构造函数; new 函数名()   this 指向 new创建的实例对象

普通函数:

function fn(){
            console.log( this )
        }
        //1.普通函数
 fn()  // this 指向 window

构造函数:

 //2.构造函数
 function fn(){
            console.log( this )
        }
 new fn()  //this指向new创建的实例对象 

对象方法:

//3.对象方法
function fn(){
            console.log( this )
        }
 let obj = {
     name:'张三',
     age:20,
     eat:fn
 }
  obj.eat()  // this 指向对象  
  • 这里给大家分享一个小技巧:
  • (1) 首先看有没有点“.” 点语法是对象使用的那么this肯定是指向对象(Object)
  • (2) 没有点就看有没有new.那么有new的话就是指向new实例对象。没有new指向window

这里有个this指向测试题:

let obj = {
      a: 1,
      c: 2,
      say: function (a) {
        console.log("this1: " + this)//(1)obj
        let sayA = function (a) {
          console.log("this2: " + this)//(2)//window
          this.a = a// window.a = 3
        }
        function sayC() {
          console.log("this3: " + this)//(3)//window 
        }
        sayA(a)//sayA(3)
        sayC()
      }
    }
    obj.say(3)
    console.log("this4: " + obj.a)//(4)1
    console.log("this5: " + obj.c)//(5)2

函数上下文调用

函数上下文调用就是改变this指向,JavaScript 中还允许指定函数中 this 的指向,有 3 个方法可以动态指定普通函数中 this 的指向

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

1、call()

// 函数名.call(修改this, 参数1 , 参数2 ...)

//声明函数
 function fn(a,b){
     console.log(this)
     console.log(a,b)
 }
 //普通函数
 fn()  //this指向window,不能被修改
 
 //(1)函数名.call(修改的this,参数1,参数2...)
 fn.call({name:'老铁'},10,20)
image.png

2、apply()

//语法: 函数名.apply(修改this, 数组/伪数组 )

//声明函数
  function fn(a,b){
      console.log(this)
      console.log(a,b)
  }
  //普通函数
  fn()//this指向window,不能被修改
  
 //(2)函数名.apply(修改this, 数组/伪数组 )
 // apply()底层会自动帮我们 遍历数组,然后逐一传参
  fn.apply({name:'李四'}, [30,40] )
image.png

3、bind()

语法:函数名.bind(修改this, 参数1 , 参数2 ...)

//声明函数
function fn(a,b){
    console.log(this)
    console.log(a,b)
}
//普通函数
fn()//this指向window,不能被修改

//(3)函数名.bind(修改this)
/* 函数名.bind()不会立即调用函数,而是得到一个修改this之后的新函数 
bind()用于不需要立即调用,而是等一会儿调用的函数 :  定时器、事件处理函数
*/
let newFn = fn.bind({name:'王五'} )
 newFn(88,99)
image.png

callapplybind三者区别

(1)相同点 : 作用一致,都是修改函数的this
(2)不同点 :
a.传参方式不同 : call()是逐个传参,apply()是数组/伪数组传参
b.执行机制不同 : call()、apply() 立即执行函数,bind()不会立即执行而是得到修改this后的新函数