学习 apply 和 call

Function.prototype.apply() & Function.prototype.call()

官方描述

  1. apply() 方法在指定 this 值和参数(参数以数组或类数组对象的形式存在)的状况下调用某个函数。fun.apply(thisArg[, argsArray])javascript

  2. call() 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。fun.call(thisArg[, arg1[, arg2[, ...]]])java

  3. 二者基本一致,只有一个区别,就是call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组。segmentfault

注意点
thisArg: 在 fun 函数运行时指定的 this 值。须要注意的是,指定的 this 值并不必定是该函数执行时真正的 this 值,若是这个函数处于非严格模式下,则指定为 nullundefined 时会自动指向全局对象(浏览器中就是window对象,说明thisArg能够不传),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象(Number,String,Boolean)。数组

温故

call为例,apply把后面参数转化成数组格式便可浏览器

  1. 在调用一个存在的函数时,为其指定一个全新的 this 对象(原函数的this对象这次调用被覆盖),而且能够传递参数,app

    function test(a) {
        console.log(this.one);
        console.log(a)
    }
    test.call({one:1},2)
    //  1
    //  2
    //咱们在test函数执行的时候绑定一个对象 {one:1} 和参数 2
  2. 调用父构造函数,实现继承函数

    function a(a) {
        this.a = a
    }
    function b(b) {
        this.b = b
    }
    //想要建立一个实例对象拥有a和b里面的属性
    function c(a,b){
        //至关于a,b函数执行了一次,因此属性会被建立
        a.call(this,a)
        b.call(this,b)
    }
    //效果等同于
    function c(a,b){
        this.a = a;
        this.b = b
    }
    var d = new c(1,2);
    d会同时用于a,b的属性,这样在涉及到不少属性继承时候就很方便
    //c {a: 1, b: 1}
  3. 使用call方法调用匿名函数,引用官方示例,其实和1相似this

var animals = [
      {species: 'Lion', name: 'King'},
      {species: 'Whale', name: 'Fail'}
    ];
    
    for (var i = 0; i < animals.length; i++) {
      (function (i) { 
        this.print = function () { 
          console.log('#' + i  + ' ' + this.species + ': ' + this.name); 
        } 
        this.print();
      }).call(animals[i], i);
    }
    // #0 Lion: King
    // #1 Whale: Fail

知新(for me)

因为call方法须要穷举全部须要传递的参数,因此只能在已知参数的状况下使用,apply则零活不少,可是接收参数的状况是同样的,apply能够将数组形式默认转化成一个参数列表 参数[a,b,c]会以(a,b,c)的形式接收。
举例来讲:prototype

//比较一组数据大小
 Math.max(9,2,4,6,7) // 9
 Math.max([9,2,4,6,7]) // NaN
//由于Math.max 方法不能接收一个数组 ,因此咱们能够进行遍历
var arr = [9,2,4,6,7],arr_len = arr.length,maxNumber = arr[0];
for(var i = 1 ;i< arr_len ;i++){
maxNumber = Math.max(maxNumber,arr[i])
}
maxNumber // 9
//这样可以达到效果,可是能够有更方便高效的方法:用apply进行改造
 Math.max.apply(null,[9,2,4,6,7]) //9 
//通过apply转化,Math.max这次执行的时候真正接收的参数是  (9,2,4,6,7)
//因此相似这种原本须要写成遍历数组变量的任务 ,均可以用apply执行,Array.prototype.push也是

还有个 bind方法和这两个很相似,能够参考另外一篇内容,详细说了bind方法
javascript原生一步步实现bind分析code

以上是我的理解,若是有误,感谢指导!

相关文章
相关标签/搜索