函数的四种调用模式以及call()apply()和bind()

函数的四种调用模式

根据函数内部this的指向不同,可以将函数的调用模式分成4种

  1. 函数调用模式
  2. 方法调用模式
  3. 构造函数调用模式
  4. 上下文调用模式(借用方法模式)
函数:当一个函数不是一个对象的属性时,我们称之为函数。
方法:当一个函数被保存为对象的一个属性时,我们称之为方法。

函数调用模式

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

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

方法调用模式

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

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

构造函数调用模式

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

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

总结:分析this的问题,主要就是区分函数的调用模式,看函数是怎么被调用的。

几种特殊的this指向

  • 定时器中的this指向了window,因为定时器的function最终是由window来调用的。
  • 事件中的this指向的是当前的元素,在事件触发的时候,浏览器让当前元素调用了function

上下文调用模式

上下文调用模式也叫方法借用模式,分为apply与call

使用方法: 函数.call() 或者 函数.apply()

call、apply、bind三者的异同

同:

  • call()、apply()和bind()都可以改变this指向

  • call()、apply()用法一样

  • call()、apply()都可以调用函数

  • call()、apply()都可以给函数传实参

异:

  • call()和apply()的传参写法不一样:

  • call(this对象,参数1,参数2,参数3)

  • apply(this对象,[参数1,参数2,参数3])

  • 如果传的参数较少且不是数值或者为数组,适合call()

  • 如果传的参数是数组或者是位数组,适合apply()

  • bind用法和call()、apply()都不一样,bind会克隆调用它的函数并通过第一个参数改变该函数的this,最后返回一个新函数(this改变),原函数this不变
    // var newfn = fn.binde(this对象)

call方法

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

//所有的函数都可以使用call进行调用
//参数1:指定函数的this,如果不传,则this指向window
//其余参数:和函数的参数列表一模一样。
//说白了,call方法也可以和()一样,进行函数调用,call方法的第一个参数可以指定函数内部的this指向。
fn.call(thisArg, arg1, arg2, arg2);
  • 借用对象的方法
// call()练习:使用数组方法向位数组中添加属性,并且length属性也要相应改变
// 非严格模式下JS中分号是不必的,但在()、{}、[]前面必须有分号
var obj = {
    0: "马超",
    1: "关羽",
    2: "张飞",
    length: 3
}
    ;[].push.call(obj, "黄忠")
console.log(obj);//{0: "马超", 1: "关羽", 2: "张飞", 3: "黄忠", length: 4}
apply方法

apply()方法的作用和 call()方法类似,只有一个区别,就是apply()方法接受的是一个包含多个参数的数组。而call()方法接受的是若干个参数的列表

call和apply的使用场景:

  • 如果参数比较少,使用call会更加简洁
  • 如果参数存放在数组中,此时需要使用apply
// apply()练习:求数组中的最大值
var arr = [1, 33, 97, 22, 50, 88]
var res = Math.max.apply([], arr)
console.log(res);
bind方法

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

// 返回值:新的函数
// 参数:新函数的this指向,当绑定了新函数的this指向后,无论使用何种调用模式,this都不会改变。
var newFn = fn.bind(window);
// bind()练习
var ff = {
    name: "欧皓辰",
    lover: "池早早",
    sayLove: function () {
        // 如果不改变定时器里的this,结果this.lover=undefined,此定时器的this是window

        // 方法一:
        // var that = this 保存this到that中,定时器使用that(定时器的this改变为that)
        // 方法二:
        // this ==> ff
        // 用bind(this) 方法模式调用,此this是调用该方法的对象
        setInterval(function () {
            console.log("Dear" + this.lover + ", 我" + this.name + ",非常想你,想你想的睡不着");
        }.bind(this), 1000)
    }
}

ff.sayLove();//Dear 池早早 , 我欧皓辰,非常想你,想你想的睡不着
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值