• apply,call和bind的使用及区别


    1、用途

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

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

    2、this指向问题

    this的指向有以下四种情况:

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

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

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

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

        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);
    }
    showName();

    我们在这里直接定义了一个方法,并且调用了它,上面说了,谁调用函数,函数里面的this就指向谁,但是我们这里直接调用了showName(),并没有明确说明是谁调用了它啊,其实这里我们可以理解为window.showName()即this实际上是指向的window。

    3、apply和call

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

    Function.prototype.call=function(context){
    // 这里的this指向demo函数
    console.log(this); context=context?Object(context):window; context.fn=this; var args=[];
    // 参数从1开始循环因为第一个参数是context for(var i=1;i<arguments.length;i++){ args.push("arguments["+i+"]"); }
    // 这里执行context.fn() 即上面的demo(),所以this指向了context,但是因为我们没有传递context,所以this指向了window 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

    4、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
  • 相关阅读:
    4.0中的并行计算和多线程详解(一)
    Dojo工具包简介
    javascript中event.keyCode
    iText简介(转)
    ServletContext
    java文件加解密算法
    ResultSet 的相关介绍
    spring的AOP的四种实现方式
    java实现文件zip压缩或者解压缩
    Hibernate查询数据的几种方式以及HQL用法及参数的几种使用方法
  • 原文地址:https://www.cnblogs.com/fiona-zhong/p/11369534.html
Copyright © 2020-2023  润新知