apply,call和bind的使用及区别

一、用途javascript

  1)apply,call和bind都是 用来改变this的指向java

  2)apply和call会让当前函数当即执行,而bind会返回一个函数,后续须要的时候再调用执行数组

二、this指向问题app

this的指向有如下四种状况:函数

  1)若是函数中的this没有调用对象,则this指向window(严格模式下,this为undefined)this

  2)若是函数中this被不包含子对象的对象调用,则this指向调用它的对象spa

  3)若是函数中this被包含多级对象的对象调用,则this指向调用它的上一级对象prototype

  4)若是咱们调用了对象,并将其赋值给某个变量,而后在须要的时候再去调用执行它,则此时this也是指向的window对象,如:code

    var a = obj.myFunc;对象

    a();

var name="zhang";
var age=18;
var obj={
    name:"liu",
    myAge:this.age,
    myFun:function(){
        console.log(this);  // this指向obj
        console.log(this.name+";"+this.age)
    }
}

obj.myAge  // 18
obj.myFun()

上图是咱们很经常使用的一个对象属性的获取和方法的调用,在咱们获取obj.myAge属性时,这里的this实际是window对象,因此咱们去找window.age,找到的是全局参数age=18

在调用myFun()方法时,本着谁调用this就指向谁的基本原则,此时this指向的是obj对象,因此咱们输出的this.name为liu,this.age为undefined

上面的例子若是不太好理解的话,咱们看下面这个更直观的例子:

var name="zhangsan";
function showName(){
    console.log(this);
    console.log(this.name);
}
show();

咱们在这里直接定义了一个方法,而且调用了它,上面说了,谁调用函数,函数里面的this就指向谁,可是咱们这里直接调用了show(),并无明确说明是谁调用了它啊,其实这里咱们能够理解为window.show()即this其实是指向的window。

 

三、apply和call

  1)先来看看call是如何实现的:

Function.prototype.call=function(context){
    context=context?Object(context):window;
    context.fn=this;
    var args=[];
    for(var i=1;i<arguments.length;i++){
        args.push("arguments["+i+"]");
    }
    var r = eval("context.fn("+args+")")
    delete context.fn;
    return r;
}
var name="test"
function demo(){
  console.log(this)
  console.lot(this.name)
}
demo.call();

  1)  当咱们传递了context时,context为咱们传递的对象;不然为window对象。

  2)  谁调用,this指向谁,咱们经过demo.call 调用了call方法,因此这里的this指向的时demo函数

  3)将传递的参数放进args中

  4)经过eval函数执行咱们的context.fn,即上面的demo函数

  5)demo函数中,this指向的时call方法中的context,这里时window对象

  6)this.name即window.name

2)call实际上是apply的一个语法糖,他们的做用都是用于改变上下文的指向,区别在于,call接受多个参数,而apply接受的是一个数组

var db={
  name:"dema"
}
var obj={
    name:"obj",
    myFunc:function(from,to){
        console.log(this);
        console.log(this.name+"来自:"+from,+"去往:"+to);
    }
}
obj.myFunc.call(null,'北京','上海')  // this 指向window,this.name=undefined,from=北京,to=上海
obj.myFunc.call(db,'北京','上海');  // this指向db,this.name='dema',from=北京,to=上海
obj.myFunc.apply(db,['北京','上海']);  // this指向db,this.name='dema',from=北京,to=上海

上面例子中,咱们分别调用了call和apply,并传入了参数null,db和地名,从上面的call的实现中,能够看到,咱们接受的第一个参数是上下文context,用于改变this的指向。

因此上面第一行,传入的context为null,则this指向window,第二行和第三行,都传人了context为db,因此this此时是指向db的,即this.name=db.name

四、bind

bind也是用于改变上下文的指向,它和call同样,接受多个参数。

bind和apply,call的区别在于,bind返回一个方法,用于后面调用,apply和call会直接执行

function print(a,b,c){
    console.log(a,b,c)
}

var fn = print.bind(null,'D')
fn('A','B','C')  // D,A,B
相关文章
相关标签/搜索