zoukankan      html  css  js  c++  java
  • javascripth函数方法apply()和call()详解

    1、引入

    在javascript中,函数也是对象,对象中可以包含属性和方法,而JavaScript的每个函数都会拥有apply和call两个非继承而来的方法。这两个都可以改变函数调用者(即this)的指向

    什么意思?

    设想一下这样一个场景,对象obj1中有一个方法fn(即函数)实现了一个功能,对象obj2也想拥有这样的功能,但它又不想增加一样的函数,因为这样做的话会使得重复代码过多,那么obj2可不可以在想用这个功能时问obj2借一下它的方法fn用一下呢?

    答案是可以的,就是使用apply和call方法,下面了解一下apply方法和call方法的使用和异同

    2、变量说明

    原始调用者:obj1

    更改后的调用者:obj2

    要改变调用者的函数:fn

    参数数组:param_array

    参数:param1,param2...

    3、apply用法

    接收两个参数:obj1.fn.call(obj2,param_array)

    效果相当于:obj2.fn(...param_array)

    注:...是ES6新增的操作符,相当于将param_array中的元素作为fn的参数依次传入

    即obj2暂时拥有了fn这个方法(函数),并且param_array

    例:

    var obj1 = {
        //求和
        add: function(...arr){
            var sum = 0
            for(var i = 0; i < arr.length; i++){
                sum += arr[i]
            }
            return sum
        }
    }
    var obj2 = {
        //求平均值
        average: function(...arr){
            //暂时借用obj1的求和方法,相当于this.add(...arr)
            var sum = obj1.add.apply(this,arr)
            return sum/arr.length
        }
    }
    console.log(obj1.add(1,2,3,4))        //10
    console.log(obj2.average(1,2,3,4))    //2.5

    常见应用:求数组最大值

    var arr = [1,5,3,4,2]
    console.log(Math.max.apply([],arr))        //5,这里的第一个参数实际上可以写任意对象
    console.log(Math.max.apply({},arr))        //5,没影响
    console.log(Math.max.apply(null,arr))      //5,传null都行    

    补充,其他求数组最大值的方式

    先降序排序取最大值,破坏原数组顺序

    var arr = [1,5,3,4,2]
    arr.sort(function(a,b){
        return b - a
    })
    console.log(arr[0])        //5

    ES6延展操作符,低版本不兼容

    var arr = [1,5,3,4,2]
    console.log(Math.max(...arr))    //5

    4、call用法

    call ()方法与 apply ()方法的作用相同,它们的区别仅仅在千接收参数的方式不同。对于caII()方法而言,第—个参数是 this
    值没有变化,变化的是其余参数都直接传递给函数。换句话说,在使用 call()方法时, 传递给函数的参数必须逐个列举出来

    接收两个(以上)参数:obj1.fn.call(obj2,param1,param2,...)

    效果相当于:obj2.fn(param1,param2,...)

    改造apply的例子:

    将average方法的var sum = obj1.add.apply(this,arr)改成var sum = obj1.add.call(this,...arr)即可

    5、该用哪个?

    在ES6的环境下,由于有延展操作符的加持,基本可以用call来搞定,而在ES5及以下环境中,主要看参数形式,如果要传的参数包含在一个数组中,推荐使用apply,否则使用call就可以了

  • 相关阅读:
    Cocos 更新时反复杀进程,导致差异更新失效的Bug
    Cocos 编译android-studio
    Could not resolve all dependencies for configuration ':classpath'
    MAC Gradle 下载的问题
    命令行创建 keystore
    应用间共享文件 FileProvider
    Android jks 签名文件 生成
    Gradle 离线 安装
    信息
    Cocos Lua的Touch 点击事件添加
  • 原文地址:https://www.cnblogs.com/chuanzi/p/10543979.html
Copyright © 2011-2022 走看看