js中对call()函数和apply()函数的深入探索

来源:互联网 发布:免费手机代理软件 编辑:程序博客网 时间:2024/05/22 04:39

call的探索

01 call借用

    //对象1   var myclass={       getAllStudentsNumbers:function(){           return 130}   };    //对象2    var student={       getDetail:function(){           return {name:'莉莉',aihao:'唱歌跳舞'}       }   };    //借用 -- 供爷法则    console.log(myclass.getAllStudentsNumbers.call(student))

02 call 传参1

 //对象1    var myclass={        getAllStudentsNumbers:function(sum,sum1){            return sum+sum1}    };    //对象2    var student={        getDetail:function(){            return {name:'莉莉',aihao:'唱歌跳舞'}        }    };    //借用 -- 供爷法则    console.log(myclass.getAllStudentsNumbers.call(student,10,200))    console.log(myclass.getAllStudentsNumbers.apply(student,[10,200]))

02 call 传参2

    //函数其实也是对象    function add(a, b) {        alert(a + b);    }    function sub(a, b) {        alert(a - b);    }    /*借用:    就是把人家的方法放到自己中来*/    add.call(sub, 3, 1);

03 call 作用 修改this

用户名:<input type="text" id="myText"   value="探索" />    var value="全局变量";    /*函数中默认this指向window*/    function Fun1(){        console.log(this.value);    }    /*答案:全局变量*/    window.Fun1();    /*答案:window*/    Fun1.call(window);    /*答案:window*/    /*可以这么理解:先把fun1变成window对象的方法,同时改变Fun1中的this指向*/    /*这个时候this表示window*/    function Fun1(){        console.log(this.value);    }    Fun1.call(document.getElementById('myText'));    /*答案*/    /*这个时候this指向input元素对象*/    //探索

05 call作用 伪数组 - 将dom元素集合数组化

    /*什么叫伪数组*/    /*伪数组:只有数组的部分功能:length,下标,无法访问数组对象中的方法*/    /*Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组*/    /*这是一种固定用法*/    /*为什么需要学习伪数组*/   /*js中常见的伪数组:通过document获取的dom集合*/    /*最为常用的arguments*/    /*这些伪数组无法使用Array对象中的方法,因为他们不是数组对象,就是普通的含有length属性的json对象而已*/  /*  比如:var json = {1:'',2:'',length:2}*/    var divs = document.getElementsByTagName("div")    console.log(divs.length)    /*说明他不是一个数组,无法访问里面的方法*/    divs.pop().style.background='green'//报错    /*我们通过如下方式将其转换成数组*/    /* slice : 截取数组,返回的还是数组,这里我们截取全部  */    var domNodes =  Array.prototype.slice.call(divs);    /*这样domNodes就可以应用Array下的所有方法了。*/    domNodes.pop().style.background='green'

06 将arguments数组化

function add(){        var sum=0;       /* arguments.push(10)  //报错*/        var arr = Array.prototype.slice.call(arguments)        arr.push(10)  //报错        for(var i=0;i<arr.length;i++){            sum+=arr[i]        }        return sum;    }    var sum = add(1,2,3,4,5)    console.log(sum)

07 将自定义伪数组数组化

    var fackArray1 = {0:'first',1:'second',length:2};    Array.prototype.slice.call(fackArray1);//  ["first", "second"]    var fackArray2 = {length:2};    Array.prototype.slice.call(fackArray2);//  [undefined, undefined]

aplay的探索

02 妙用1 参数数组拆分法则 - 计算数组最大值

 /* 我们先从Math.max()函数说起,    Math.max后面可以接任意个参数,最后返回所有参数中的最大值。    比如*/   console.log(Math.max(5,8)) //8   console.log(Math.max(5,7,9,3,1,6)) //9   /*问题:如何获取一个数组的最大值*/   /*遍历*/   /* 但是在很多情况下,我们需要找出数组中最大的元素。*/   /* var arr=[5,7,9,1]    alert(Math.max(arr)) // 这样却是不行的。一定要这样写*/    /*传统方式写法*/    function getMax(arr){        var arrLen=arr.length;        for(var i=0,ret=arr[0];i<arrLen;i++){            ret=Math.max(ret,arr[i]);    }    return ret;    }   console.log(getMax([1,2,3,4,5,6,7]))    /*这样写麻烦而且低效。如果用 apply呢,看代码:*/   /*参数数组拆分法则*/   /*传递一个数组,其实会将其拆成很多个参数*/   /*适用场景:函数可以接受不限个数的参数*/   /*这样我们只能使用arguments来管理可变参数*/   /*比如max min push join split replace*/   /*在js中有很多这样支持可变参数的函数   大家还记得我们前面写的extend,也是支持可变参数*/   /*这也是为什么apply这么流行,这么重要的原因*/   /*广泛运用在框架,算法中*/   /*巧用apply虽然传递的是数组,但是使用的时候是把数组拆开的。。   等价于  return Math.max.call(null,1,2,3,4,5);*/   /*所以等价于:Math.max(5,7,9,3,1,6)*/    function getMax2(arr){        return Math.max.apply(null,arr);       /* return Math.max.call(null,1,2,3,4,5);*/    }   console.log(getMax2([1,2,3,4,5,6,7]))

03 练习 计算最小值

 //计算最小值    /*参数数组拆分法则*/    /*传递一个数组,其实会将其拆成很多个参数,正好符合min的语法*/    var min=Math.min.apply(null,[3335,333,34343,34343,5657767,34455,445466,45454,343434,46466,56556,464646,464646,466,4646464])    alert('最小值:'+min)

04 练习 将一个数组的值合并到另一个数组

  /*练习*/    /*将一个数组合并到另一个数组中*/    var arr1=new Array("1","2","3");    var arr2=new Array("4","5","6");    /*最终arr1["1","2","3","4","5","6"]*/    //传统写法    function PushArray(arr1,arr2){        var arrLen=arr2.length        for(var i=0;i<arrLen;i++){            arr1.push(arr2[i])        }        return arr1;    }    var result = PushArray(arr1,arr2);    console.log(result)    /*使用apply写法*/     /*Array.prototype.push 可以实现两个数组合并     同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN)     push(arr,2,3,3,3,3)     所以同样也可以通过apply来装换一下这个数组,即:*/    Array.prototype.push.apply(arr1,arr2);   /* Array.prototype.push.call(arr1,"4","5","6");*/   /*  push(arr1,"4","5","6")*/    console.log(arr1)    console.log(arr2)

05 自定义的函数

 /*有的说 这样的函数也不多,apply应该也就使用部分函数而已,。。。。大打错了。    下面看下高手的编程    工作中70%用不好apply    50%都不理解apply    后台开发人员也做部分前端 80%都不知道这个用法*/    function add(a, b) {        return a + b;    }    function add(){        var sum=0;        for(var i=0;i<arguments.length;i++){            sum+=arguments[i]        }        return sum;    }    var sum = add(1,2,3,4,5)    console.log(sum)    /*如何计算数组的和*/    var sum2 =  add.apply(null,[1,2,3,4,5])    console.log(sum2)

06 总结:调用函数的5种方式

 /******************************************************************************                                            普通模式     *******************************************************************************/    // 声明一个函数,并调用    function func() {        console.log("Hello World");    }    func();    /******************************************************************************                                            函数表达式     *******************************************************************************/    // 使用函数的Lambda表达式定义函数,然后调用    var func = function() {        console.log("你好,传智播客");    };    func();    //可以发现函数调用很简单,就是平时学习的一样.    //这里的关键是,在函数调用模式中,函数里的 this 关键字指全局对象,    //如果在浏览器中就是 window 对象. 例如:    var func = function() {        console.log(this);    };    func();    //    此时,会弹出对话框,打印出 [object Window]    /******************************************************************************                                    方法调用模式     *******************************************************************************///    函数调用模式很简单,是最基本的调用方式.//    但是同样的是函数,将其赋值给一个对象的成员以后,就不一样了.//    将函数赋值给对象的成员后,那么这个就不在称为函数,而应该叫做方法.    // 定义一个函数    var func = function() {        alert("我是一个函数么?");    };    // 将其赋值给一个对象    var o = {};    o.fn = func; // 注意这里不要加圆括号    // 调用    o.fn();//    此时,o.fn 则是方法,不是函数了.//    实际上 fn 的方法体与 func 是一模一样的,但是这里有个微妙的不同. 看下面的代码:    // 接上面的代码    alert(o.fn === func);//    打印结果是 true ,这个表明两个函数是一样的东西. 但是修改一下函数的代码:    // 修改函数体    var func = function() {        alert(this);    };    var o = {};    o.fn = func;    // 比较    alert(o.fn === func);    // 调用    func();    o.fn();    // 这里的运行结果是,两个函数是相同的,因此打印结果是 true.    // 但是由于两个函数的调用是不一样的,    // func的调用,打印的是 [object Window],而o.fn 的打印结果是[object Object].    // 这里便是函数调用与方法调用的区别.    // 函数调用中,this专指全局对象window,    // 而在方法中this专指当前对象. 即o.fn 中的this 指的就是对象o.    /******************************************************************************                                        构造函数调用模式     *******************************************************************************///    同样是函数,在单纯的函数模式下,this表示window;//    在对象方法模式下,this指的是当前对象.//    除了这两种情况,JavaScript中函数还可以是构造器.//    将函数作为构造器来使用的语法就是在函数调用前面加上一个new关键字. 如代码:    // 定义一个构造函数    var Person = function() {        this.name = "传智播客";        this.sayHello = function() {            alert("你好,这里是" + this.name);        };    };    // 调用构造器,创建对象    var p = new Person();    // 使用对象    p.sayHello();//    上面的案例首先创建一个构造函数Person,然后使用构造函数创建对象p.//    这里使用 new语法.然后使用对象调用sayHello()方法.//    这个使用构造函数创建对象的案例比较简单. 从案例可以看到,此时 this指的是对象本身.    /******************************************************************************                                    apply call调用模式     *******************************************************************************/        //前面已经详细讲解了        /*Function对象定义函数*/

07 apply实现继承 - 继承的简单介绍

//     apply实现继承//    学生类本来不具备任何方法,//    但是在 Person.apply(this,arguments)  后,//    他就具备了 Person类的sayhello方法和 所有属性。//    在 Print.apply(this,arguments) 后就自动得到了  show() 方法。    //人对象    function Person(name,age){        this.name=name     //名字        this.age=age       //年龄        this.sayhello=function(){            console.log("人对象方法")        }    }    Person.prototype={        buy:function(){            console.log('测试是否能够继承原型中的方法')        }    }    //输出打印对象    function Print(){            //显示类的属性        this.funcName="我是打印对象"        this.show=function(){           console.log ('打印对象方法')        }    }    //学生对象    function Student(name,age,grade,school){    //学生类        Person.apply(this,arguments)        Print.apply(this,arguments)        this.grade=grade                  //年级        this.school=school                    //学校    }    /*子类继承两个父类*/   /* 也就是通俗一点讲就是:    用student去执行Person这个类里面的内容,    在Person这个类里面存在this.name等之类的语句,    这样就将属性创建到了student对象里面*/    var lisi=new Student("tom",13,6,"清华小学")    //学生继承了人和打印对象,则拥有了人的属性和方法    /*打印父类*/    lisi.show()    /*人父类*/    lisi.sayhello()    /*无法继承原型对象中的方法*/    alert(lisi.buy())
原创粉丝点击