this与函数的四种调用模式

251 阅读2分钟

this与函数的四种调用模式

  1. 函数调用模式
  2. 方法调用模式
  3. 构造函数调用模式
  4. 上下文调用模式(借用方法模式)

函数调用模式

如果一个函数不是一个对象的属性时,就是被当做一个函数来进行调用的。此时this指向了window

function fn(){
  console.log(this);// 指向window 
}
fn();

方法调用模式

当一个函数被保存为对象的一个属性时,我们称之为一个方法。当一个方法被调用时,this被绑定到当前对象

const obj = {
  sayHi:function(){
    console.log(this);//在方法调用模式中,this指向调用当前方法的对象。
  }
}
obj.sayHi();

构造函数调用模式

如果函数是通过new关键字进行调用的,此时this被绑定到创建出来的新对象上。

function Person(){
  console.log(this);
}
Person();//this指向什么?   window
var p = new Person();//this指向什么?  Person{}

方法借用模式

也叫上下文模式,分为 apply 与 call,bind

call

call方法可以调用一个函数,并且可以指定这个函数的this指向

const RichWumon = {
    name: "土豪",
    say: function () {
        console.log(this.name);
    }
}

const obj = {
    name: "屌丝"
}

RichWumon.say();			// 土豪
RichWumon.say.call(obj);	// 屌丝

call将伪数组转成数组

伪数组不能使用数组的api,如果需要用数组api给伪数组添加元素,则需要使用call()方法

添加单个元素

let arr = {
        0: 1,
        1: 10,
        2: 200,
        length: 3
      }
      // 第一个参数是this,后面的是参数列表
      ;[].push.call(arr, 300)
      console.log(arr)   //{0: 1, 1: 10, 2: 200, 3: 300, length: 4}

添加一个数组

let arr = {
        0: 1,
        1: 10,
        2: 200,
        length: 3
      }
      // 第一个参数是this,后面的是参数列表
      let data = [50, 60, 70, 80, 90]
      ;[].push.call(arr, ...data)
      console.log(arr)    
	  // arr:{0: 1, 1: 10, 2: 200, 3: 50, 4: 60, 5: 70, 6: 80, 7: 90, length: 8}

apply

apply()方法接受的是一个包含多个参数的数组

 let arr = {
         0: 1,
        1: 10,
        2: 200,
       length: 3
       }
      
      // 如果有参数,参数需要定义为数组或伪数组
       ;[].push.apply(arr, [50, 60, 70, 80, 90])
       console.log(arr)

bind方法

**bind()**方法创建一个新的函数, 可以绑定新的函数的this指向

 var name = '张三'
 function Fn() {
            this.age = 1
            console.log(this.name + this.age)
        }
        Fn() // 张三 1
        // 返回值:新的函数
        // 参数:新函数的this指向,当绑定了新函数的this指向后,无论使用何种调用模式,this都不会改变。
        let obj = {
                name: '小强'
            }
            // bind:返回一个新的函数,且函数中的this为你所传入的参数
        const newFn = Fn.bind(obj)
        newFn()