apply 、bind 、call小结

call、apply、bind

首先说call、apply、bind的作用是改变函数运行时this的指向。
说一下this,谁调用,this就指向谁:

document.addEventListener('click', function(e){
    console.log(this);//document
    setTimeout(function(){
        console.log(this);//window
    }, 200);
}, false);

其中setTimeout内的函数属于回调函数,可以这么理解,console.log.call(null,window),所以this指向window。
普通声明一个函数
function s(){
console.log(this);//window
}
函数s是挂到window下的,所以this指向window。
但是把函数赋值到对象上以后

var a = 1
var obj1 = {
    a:2,
    fn:function(){
        console.log(this.a)
    }
}
var fn1 = obj1.fn
fn1()//1

此时fn1就是不带任何的call apply,
function(){console.log(this.a)}.call(undefined),这种情况浏览器里有一条规则:
如果你传的 context 就 null 或者 undefined,那么非严格模式下 window 对象就是默认的 context(严格模式下默认 context 是 undefined)也被称为隐性绑定。
如果fn1.call(obj1),则输出的就是2

【1】call

call当第一个参数为null、undefined的时候,默认指向window。后面的其余参数分别一一对应参数列表

var arr = [1, 2, 3, 89, 46]
var max = Math.max.call(null, arr[0], arr[1], arr[2], arr[3], arr[4])//89

//简化思路(参考的大神思路https://www.jianshu.com/p/bc541afad6ee)
obj1.fn() 
obj1.fn.call(obj1);

fn1()
fn1.call(null)

f1(f2)
f1.call(null,f2)

【2】apply

apply接受两个参数,第一个参数是要绑定给this的值,第二个参数是一个参数数组。当第一个参数为null、undefined的时候,默认指向window。

var arr = [1,2,3,89,46]
var max = Math.max.apply(null,arr)//89

小结:
apply 和 call 的用法几乎相同, 唯一的差别在于:当函数需要传递多个变量时, apply 可以接受一个数组作为参数输入, call 则是接受一系列的单独变量。
在 ES6 的箭头函数下, call 和 apply 将失效

【3】bind

第一个参数是this的指向,从第二个参数开始是接收的参数列表。和call区别是bind方法返回值是函数。而call是改变this指向并调用函数,bind是改变this指向并返回函数(如果想执行的话需要调用())
例子:

var obj = {
    name: 'a'
}

function printName() {
    console.log(this.name)
}

var afun= printName.bind(obj)
var bfun= printName.call(obj)
console.log(afun) // ƒ printName() {console.log(this.name)}
afun()  // a
console.log(bfun) // a
bfun()  //VM1252:11 Uncaught TypeError: afun is not a function

总结:

1、apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
2、apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
3、apply 、 call 、bind 三者都可以利用后续参数传参(apply第二个参数是一个参数数组);
4、bind 是返回对应函数(稍后调用);apply 、call 是立即调用 。

【4】利用call和apply做继承

function Person(name,age){
    // this都指向实例
    this.name = name
    this.age = age
    this.sayAge = function(){
        console.log(this.age)
    }
}
function Female(){
    Person.apply(this,arguments)//将父元素所有方法在这里执行一遍就继承了
}
var dot = new Female('Dot',2)

参考:https://www.jianshu.com/p/bc541afad6ee

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值