zoukankan      html  css  js  c++  java
  • 闲聊js中的apply、call和arguments

             JavaScript提供了apply和call两种调用方式来确定函数中的this的指向,在现实编码中,我确实

    很少接触到这两个方法。但很无奈,很多面试题都要考这两种方法,我又没怎么用到,所以我们先来

    闲聊下他们到底有什么用和到底怎么用。
             我们先来聊一下apply的用法吧,它是用来改变函数的指向的,说白了,就是指向了别的函数的作用域。

    例如看一下下面这个例子。

    var A={
        name:"我是小A",
        fun:function(){
            console.log("大家好! "+this.name)
        }
    }
    
    var B = {
        name:"我是小B"
    }
    
    A.fun();           //大家好! 我是小A
    A.fun.apply(B);    //大家好!  我是小B

    可以看出来,当我们使用了apply将引用指向了B时,A调用fun时并不是调用本身中的name  而是调用了B中的那么;

    但如果我们在调用函数中并没用引用到this,那么是不是说apply就失去了意义?再来看一下下面的例子

    var A={
        name:"我是小A",
        fun:function(num,money){
            console.log("大家好! "+this.name+" 我有"+num+"张"+money+"块")
        }
    }
    
    var B = {
        name:"我是小B"
    }
    var monies = [10,20];
    
    A.fun.apply(B,monies);    //大家好! 我是小B 我有10张20块

    可以看出:apply中

      第一个参数为thisObject,调用时采用传入的thisObject代替函数体中this的指向

     第二个参数传入一个数组,函数会用数组的值取代“参数列表"。

          这里聊一下monies,就要说到参数列表,当然我们会想到arguments,在这里插入聊一下arguments。网

    上arguments是具有数组某些特性的‘类数组‘(伪数组);其实JS并没有重载函数的功能,但是auguments对象

    能够模拟重载。每个函数都有一个Arguments对象实例arguments,它引用着函数的实参,可以用数组下

    标的方式”[]“引用arguments的元素。arguments.length为函数实参个数。

    function test() {
            var s = "";
            for (var i = 0; i < arguments.length; i++) {
                alert(arguments[i]);
                s += arguments[i] + ",";
            }
            return s;
        }
        test("name", "age")

    输出

    name,age

    匿名函数中可以用arguements.callee引用函数自身。

    例如 function(){

             if(n>0) return 0;

              else return n+arguments.callee(n+1);

    }

    回归正题,我们可以用arguments来代替函数中的参数

    var A={
        name:"我是小A",
        fun:function(num,money){
            console.log("大家好! "+this.name+" 我有"+arguments[0]+"张"+arguments[1]+"块")
        }
    }
    
    var B = {
        name:"我是小B"
    }
    var monies = [10,20];
    
    A.fun.apply(B,monies);    //大家好! 我是小B 我有10张20块

    这里又有一个问题,可不可以用Array.prototype.shift.apply(arguments)来代替arguments[0]呢?直接看代码

    var A={
        name:"我是小A",
        fun:function(num,money){
            console.log("大家好! "+this.name+" 我有"+Array.prototype.shift.apply(arguments)+"张"+arguments[1]+"块")
        }
    }
    
    var B = {
        name:"我是小B"
    }
    var monies = [10,20];
    
    A.fun.apply(B,monies);    //大家好! 我是小B 我有10张undefined块

            当我们使用Array.prototype.shift.apply(arguments)调用之后,arguments[0]就会被抹去,所以arguments[1]就会冒到arguments[0]上。

    这可以看出arguments这个”伪数组“,除了不是”原型继承自’Array.prototype‘“职位,其他特征和数组是一样的。

            最后,我们考虑一下,如果使用apply方法时,传入的第一个参数是null时,调用函数时,会发生什么情况,会不会报错呢!

    不多说,直接上例子

    var A={
        name:"我是小A",
        fun:function(num,money){
            console.log("大家好! "+this.name+" 我有"+num+"张"+money+"块")
        }
    }
    
    var B = {
        name:"我是小B"
    }
    var monies = [10,20];
    name="我是小C"
    
    A.fun.apply(null,monies);    //大家好! 我是小C 我有10张20块

    可以看到  如果第一传入的参数是null的话,在函数提内的this会指向全局对象,在浏览器中就是window。

    所以可以总结出两点:

    1.如果函数中有明确使用this,那么this就会指向传入的第一个参数的作用域。

    2.如果传入的第一参数为null时,this就会指向全局的作用域。

    apply的另一种用法就是用于将数组分割为一个个元素。

    例如想在数组中a[1,2,3,4]中寻找出最大的袁术出来。

    如果直接调用Math.max(a);就会输出NaN,所以这时候我们可以这样

    Math.max.apply(null,a);        //输出4

          聊完了apply之后,我们再聊一下call就更简单了,其实他们的作用都是一样的。他们唯一的区别就是

    apply和call在形式参数上的不同,apply只能传入两个参数且,第二个参数传入的是数组,而call在

    第二参数开始可以接受任意个参数。大家看下面的例子就一目了然了

    var A={
        name:"我是小A",
        fun:function(num,money){
            console.log("大家好! "+this.name+" 我有"+num+"张"+money+"块")
        }
    }
    
    var B = {
        name:"我是小B"
    }
    var monies = [10,20];
    A.fun(monies[0],monies[1]);           //大家好! 我是小A 我有10张20块
    A.fun.apply(B,monies);               //大家好! 我是小B 我有10张20块
    A.fun.call(B,monies);                //大家好! 我是小B 我有10,20张undefined块
    A.fun.call(B,monies[1],monies[2]);    //大家好! 我是小B 我有20张undefined块
  • 相关阅读:
    linux php安装ODBC扩展
    linux wget变成000权限
    linux tomcat启动报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
    字符串的操作, 日期格式, 数据转换, 模糊查询
    Oracle控制结构
    创建角色,用户,视图,索引,分析计划
    Oracle用触发器解决修改主表A主键值,从表的外键值也会跟着改变的问题
    行为科学统计第17章--回归
    行为科学统计第13-15章
    行为科学统计第12章
  • 原文地址:https://www.cnblogs.com/binguo666/p/10533733.html
Copyright © 2011-2022 走看看