基础知识

  • 函数也是对象

call()和apply()

  • 这两个方法都是函数对象的方法,需要通过函数对象来调用

  • 当对函数调用call()apply()都会调用函数执行

    1
    2
    3
    4
    5
    6
    7
    8
    function fun(){
    alert("我是fun函数!");
    }

    //效果相同
    fun.apply();
    fun.call();
    fun();

    输出结果为:

image-20210503150938534

  • 在调用call()apply()可以将一个对象指定为第一个参数

    • 此时这个对象将会成为函数执行时的this
    • call()apply()的作用:可以修改函数执行时的上下文对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function fun(){
    alert(this);
    }

    var obj = {name:"obj"};
    var obj2 = {name:"obj2"};

    //效果相同
    fun.call(obj2.name);
    fun.apply(obj2.name);

    输出结果为:

    image-20210503153139794

    • 若直接运行fun(),输出结果为:

      image-20210503153355094

  • call()方法可以将实参在对象之后依次传递

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function fun(a,b){
    console.log("a = "+a);
    console.log("b = "+b);
    }

    var obj = {
    name:"obj",
    sayName:function(){
    alert(this.name);
    }
    };

    fun.call(obj,2,3);

    输出结果为:

    image-20210503154339384

  • apply()方法需要将实参封装到一个数组中统一传递

    1
    fun.apply(obj,[2,3]);

    输出结果同上

this的情况

  • 以函数的形式调用时,this永远都是window
  • 以方法的形式调用时,this是调用方法的对象
  • 以构造函数的形式调用时,this是新创建的那个对象
  • 使用call和apply调用时,this是指定的那个对象

arguments

  • 在调用函数时,浏览器每次都会传递进两个隐含的参数:

    1. 函数的上下文对象this
    2. 封装实参的对象arguments
  • arguments是一个类数组对象,它可以通过索引来操作数据,也可以获取长度

  • 在调用函数时,我们所传递的实参都会在arguments中保存

  • 我们即使不定义形参,也可以通过arguments来使用实参,只不过比较麻烦

    • arguments[0]表示第一个实参
    • arguments[1]表示第二个实参
  • 它里面有一个属性叫做callee

    • 这个属性对应一个函数对象,就是当前正在指向的函数对象

      arguments.callee == fun