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())
阅读全文
0 0
- js中对call()函数和apply()函数的深入探索
- js函数中两个比较有趣的方法:apply()和call()
- js中call和apply(函数的上下文调用模式)详解
- js中call和apply(函数的上下文调用模式)详解
- 关于js中call和apply函数的应用
- JS 函数call和apply
- js 的 apply / call 函数
- js(十三)——函数call和apply
- 【JS--基础--函数】--函数的通用方法-call()和apply()
- 关于js的call函数和apply函数
- 深入JavaScript(apply和call函数)
- js中call、apply、bind函数
- 对js中call、apply和bind的理解
- js的call和apply函数的使用
- js中bind、call、apply函数的用法
- js中bind、call、apply函数的用法
- js中bind、call、apply函数的用法
- js中bind、call、apply函数的用法
- android几个自定义广播和系统广播的用法
- mybatis的基本使用及配置
- c/c++中关于qsort的使用
- 异步加载js不允许使用document.write的解决方法
- 相对布局解析以及Android studio 连接夜神模拟器
- js中对call()函数和apply()函数的深入探索
- 请求筛选模块被配置为拒绝超过请求内容长度的请求。
- C语言的简单应用(一)
- 如何使用Arduino和SIM900A GPRS / GSM模块将数据发送到Web服务器
- multipath -ll输出结果中的三个状态列的解释
- Anroid_监听手机来信
- BZOJ 3527 [Zjoi2014]力
- 适配器模式
- 【转】Integer.valueof ,Integer.parseInt的区别