一、call
1、call供爷法则
1 // 对象1 2 var myclass={ 3 getAllStudentsNumbers:function(num1,num2){ 4 return num1+num2; 5 }}; 6 // 对象2 7 var student={ 8 getDetail:function(){ 9 return {name:'乐乐',like:'唱歌跳舞'} 10 } 11 }; 12 //借用 供爷法则 student可以借用myclass的方法 13 //call和apply的区别 传参的不同 14 //call是所有参数平铺,apply是将参数放在数组中进行传递 15 console.log(myclass.getAllStudentsNumbers.call(student,10,20));//30 16 console.log(myclass.getAllStudentsNumbers.apply(student,[10,20]));//30
1 //函数其实也是对象 2 function add(a, b) 3 { 4 console.log(a + b); 5 } 6 function sub(a, b) 7 { 8 console.log(a - b); 9 } 10 add.call(sub, 3, 1);//4
2、call---this
1 /*定义一个animal类*/ 2 function Animal(){ 3 this.name = "Animal"; 4 this.showName = function(){ 5 alert(this.name); 6 } 7 } 8 /*定义一个Cat类*/ 9 function Cat(){ 10 this.name = "Cat"; 11 } 12 13 /*创建两个类对象*/ 14 var animal = new Animal(); 15 var cat = new Cat(); 16 17 //通过call或apply方法,将原本属于Animal对象的showName()方法交给当前对象cat来使用了。 18 //输入结果为"Cat" 19 animal.showName.call(cat,",");//Cat 20 //animal.showName.apply(cat,[]);
3、call使用场景---数组化
将伪数组转换为数组:
var domNodes = Array.prototype.slice.call(divs);
1 /*伪数组:只有数组的部分功能:length,下标,无法访问数组对象中的方法*/ 2 var divs = document.getElementsByTagName("div") 3 console.log(divs.length); 4 /*说明他不是一个数组,无法访问里面的方法*/ 5 // divs.pop().style.background='green' 6 7 /*我们通过如下方式将其转换成数组*/ 8 var domNodes = Array.prototype.slice.call(divs); 9 /*这样domNodes就可以应用Array下的所有方法了。*/ 10 11 12 /* slice : 截取数组,返回的还是数组,这里我们截取全部 */ 13 domNodes.pop().style.background='green';
二、apply
1、基本用法
1 /*定义一个人类*/ 2 function Person(name,age) { 3 this.name=name; 4 this.age=age; 5 } 6 7 /*定义一个学生类*/ 8 function Student(name,age,grade) { 9 Person.apply(this,arguments); 10 this.grade=grade; 11 } 12 13 //创建一个学生类 14 var student=new Student("邓乐乐",24,"一年级"); 15 //测试 16 document.write("姓名:"+student.name+"\n"+"年龄:"+student.age+"\n"+"年级:"+student.grade);//姓名:邓乐乐 年龄:24 年级:一年级 17 //大家可以看到测试结果name:邓乐乐 age:24 grade:一年级 18 //学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处. 19 20 //分析: Person.apply(this,arguments); 21 // 22 //this:在创建对象在这个时候代表的是student 23 // 24 //arguments:是一个数组,也就是[“邓乐乐”,”24”,”一年级”]; 25 // 26 //也就是通俗一点讲就是: 27 // 用student去执行Person这个类里面的内容, 在Person这个类里面存在this.name等之类的语句, 28 // 这样就将属性创建到了student对象里面
2、巧妙用法
(1)Max函数用法
1 // apply的一些其他巧妙用法 2 // 细心的人可能已经察觉到,在我调用apply方法的时候, 3 // 第一个参数是对象(this), 4 // 第二个参数是一个数组集合, 5 // 在调用Person的时候,他需要的不是一个数组, 6 // 但是为什么他给我一个数组我仍然可以将数组解析为一个一个的参数, 7 // 这个就是apply的一个巧妙的用处:可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3) 这个如果让我们用程序来实现将数组的每一个项,来转换为参数的列表, 8 // 可能都得费一会功夫,借助apply的这点特性,所以就有了以下高效率的方法: 9 10 // max函数用法 11 // Math.max后面可以接任意个参数,最后返回所有参数中的最大值。 12 console.log(Math.max(5,8)) //8 13 console.log(Math.max(5,7,9,3,1,6)) //9 14 15 //但是在很多情况下,我们需要找出数组中最大的元素。 16 17 var arr=[5,7,9,1] 18 alert(Math.max(arr)) //这样却是不行的。因为其不支持传递数组过去 那么怎么做呢,就要考察我们的算法功底了。。 19 20 function getMax(arr){ 21 var arrLen=arr.length; 22 for(var i=0,ret=arr[0];i<arrLen;i++){ 23 ret=Math.max(ret,arr[i]); 24 } 25 return ret; 26 } 27 28 29 //获取数组中的最大值 30 var max=Math.max.apply(null,[1,10,122,3335,333,34343,34343,5657767,2,34455,445466,45454,343434,46466,56556,464646,464646,466,4646464]) 31 alert('最大值:'+max); 32 33 // 整体解析: 34 // 因为Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组 35 // 但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决 36 // var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项 37 // (apply会将一个数组装换为一个参数接一个参数的传递给方法) 38 // 第一个参数为什么是null: 39 // 这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法, 40 // 我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去
(2)Min计算最小值
1 //计算最小值 2 var min=Math.min.apply(null,[1,10,122,3335,333,34343,34343,5657767,2,34455,445466,45454,343434,46466,56556,464646,464646,466,4646464]); 3 alert('最小值:'+min);//1 4 5 //Math.min 可以实现得到数组中最小的一项 6 //同样和 max是一个思想 7 8 9 // Array.prototype.push 可以实现两个数组合并 10 // 同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 11 // 所以同样也可以通过apply来装换一下这个数组,即: 12 13 var arr1=new Array("1","2","3"); 14 var arr2=new Array("4","5","6"); 15 Array.prototype.push.apply(arr1,arr2); 16 alert(arr1);//1,2,3,4,5,6 17 alert(arr2);//4,5,6 18 //也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合. 19 20 21 // 传统写法 22 function PushArray(arr1,arr2){ 23 var arrLen=arr2.length 24 for(var i=0;i<arrLen;i++){ 25 arr1.push(arr2[i]) 26 } 27 return arr1; 28 } 29 var result = PushArray(arr1,arr2); 30 console.log(result);//Array(9)
3、apply实现继承
1 // apply实现继承 2 // 学生类本来不具备任何方法, 3 // 但是在 Person.apply(this,arguments) 后, 4 // 他就具备了 Person类的sayhello方法和 所有属性。 5 // 在 Print.apply(this,arguments) 后就自动得到了 show() 方法。 6 7 8 //人对象 9 function Person(name,age){ //定义一个类,人类 10 this.name=name; //名字 11 this.age=age; //年龄 12 this.sayhello=function(){console.log("人对象的某个方法")} 13 } 14 15 //输出打印对象 16 function Print(){ //显示类的属性 17 this.funcName="我是打印对象"; 18 this.show=function(){ 19 console.log ('打印对象的某个方法'); 20 } 21 } 22 23 //学生对象 24 function Student(name,age,grade,school){ //学生类 25 Person.apply(this,arguments); 26 Print.apply(this,arguments); 27 this.grade=grade; //年级 28 this.school=school; //学校 29 } 30 31 // 实例化人对象 32 var zhangsan=new Person("张三",10) 33 zhangsan.sayhello(); 34 35 // 实例化学生对象 36 var lisi=new Student("tom",13,6,"清华小学") 37 // 学生继承了人和打印对象,则拥有了人的属性和方法 38 lisi.show();//打印对象的某个方法 39 lisi.sayhello();//人对象的某个方法 40 console.log(lisi.funcName);//我是打印对象