zoukankan      html  css  js  c++  java
  • JS中call和apply

    作用:

    替换当前对象的方法中的this。

    理解:

    call和apply是为了动态改变this出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。

    用的比较多的,通过document.getElementsByTagName选择的dom 节点是一种类似array的array。

    它不能应用Array下的push,pop等方法。我们可以通过:

    var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

    这样domNodes就可以应用Array下的所有方法了。

     

    语法:

    call([thisObj[,arg1[, arg2[,   [,.argN]]]]])  ##没提供thisObj , Global 对象将被用作 thisObj。参数用逗号分隔。

    apply([thisObj [,argArray]])  ##没提供 thisObj , Global 对象将被用作 thisObj。参数为一个数组,与call的主要区别就在参数形式上,这样如果参数个数确定可以用call,如果参数个数不确定就用apply。

     

    技巧:

    1.把arguments转为数组

    function args2arr() {
        return [ ].slice.call(arguments, 0);
        //return Array.prototype.slice.call(arguments, 0);   //和上边的写法效果相同
    }
    args2arr(1, 2, 3, 5, 6, 7, 8);   //[1, 2, 3, 5, 6, 7, 8]
    arguments对象:该对象代表正在执行的函数和调用它的函数的参数。不能显式创建 arguments 对象。arguments 对象只有函数开始时才可用。函数的 arguments 对象并不是一个数组,访问单个参数的方式与访问数组元素的方式相同。
    slice: 返回一个数组的一段。arrayObj.slice(start, [end]) [start是开始的下标,end是结束的下标,end不是长度]
    所以[ ].slice.call(arguments, 0)是调用了数组的slice方法,但是对象被替换成了arguments,并且传入start参数0,就是把全部参数slice成一个新数组。

    2.返回数组中的最大值

    function argsMax() {
        // 找出对象 arguments 当中数字最大的值
        return Math.max.apply(null,arguments);
    }
    
    argsMax(1, 2, 3, 5, 6, 7, 8)  // 8

    Math.max([number1[, number2[. . . [,numberN]]]]) : 返回给出的零个或多个数值表达式中较大者。

    max本身接收用逗号分隔的参数,通过apply方法传入数组形式的参数,第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去。

    3.合并两个数组

    var arr1=new Array("1","2","3");
    var arr2=new Array("4","5","6");
    Array.prototype.push.apply(arr1,arr2);

    arrayObj.push([item1 [item2[. . . [itemN ]]]]) : 将新元素添加到一个数组中,并返回数组的新长度值。

    这里arr1作为劫持Array的push方法的对象,把arr2当做参数传入。


    例子:

    1.借用函数

    function getName() {
        return this.name
    }
    var obj = {name: "jack"};
    getName.call(obj)  //jack,js 中的函数其实是对象,函数名是对 Function 对象的引用。

    2.借用对象方法

    var obj1 = {
        name: "panxuepeng",
        getName: function() {return this.name}
    }
    var obj2 = {name: "jack"};
    obj1.getName.call(obj2)  //jack

    3.稍复杂的对象

     //构造函数,对应的对象就是Animal.   
     function Animal(){    
            this.name = "Animal";    
            this.showName = function(){    
                alert(this.name);    
            }    
        }    
          
        function Cat(){    
            this.name = "Cat";    
        }    
           
        var animal = new Animal();    
        var cat = new Cat();    
                
        animal.showName.call(cat); //Cat,调用对象中的方法必须先实例化类
        /*
         *调用Animal对象的方法showName必须先实例化Animal类,如果只是调用属性
         *可以直接Animal.property就行
         *所以上边的写成Animal.showName.call会报错
         */    
        //animal.showName.apply(cat,[]);  

    4.继承

        function Animal(name){      
            this.name = name;      
            this.showName = function(){      
                alert(this.name);      
            }      
        }      
            
        function Cat(name){    
            Animal.call(this, name);    
        }      
            
        var cat = new Cat("Black Cat");     
        cat.showName();  //Black Cat

     

  • 相关阅读:
    组合 聚合 依赖 关联
    effective C++ 总结
    重讲设计模式
    宏定义要加括号
    enum hack
    MFC 刷新函数:Invaldate,UpdateWindow,InvaldateRect
    MFC onchar()
    win7系统自带分区工具,能分出逻辑分区
    窗口的创建步骤
    私话编译连接运行过程以及动态库、静态库
  • 原文地址:https://www.cnblogs.com/leezhxing/p/4272874.html
Copyright © 2011-2022 走看看