第195天:js---函数对象详解(call、apply)

简介: 一、call1、call供爷法则 1 // 对象1 2 var myclass={ 3 getAllStudentsNumbers:function(num1,num2){ 4 return num1+num2; 5 }}; 6 // 对象...

一、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);//我是打印对象

 

相关文章
|
11天前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
15天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
15天前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
28 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
14天前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
15天前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
28天前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
2月前
|
JavaScript 前端开发
JavaScript基础知识-函数的参数
关于JavaScript函数参数基础知识的介绍。
27 4
JavaScript基础知识-函数的参数
|
2月前
|
JavaScript 前端开发
JavaScript 函数参数
JavaScript 函数参数
30 3
|
4月前
|
JavaScript 前端开发 网络架构
JavaScript编码之路【对象的增强、ES6新特性之函数的默认值设置 、rest参数 (剩余参数)、拓展运算符、对象与数组的解构赋值】
JavaScript编码之路【对象的增强、ES6新特性之函数的默认值设置 、rest参数 (剩余参数)、拓展运算符、对象与数组的解构赋值】
57 1
|
5月前
|
JavaScript
js -- 函数总结篇,函数提升、动态参数、剩余参数、箭头函数、this指向......
js -- 函数总结篇,函数提升、动态参数、剩余参数、箭头函数、this指向......