第10天(apply和callbind函数作为参数返回值使用闭包递归的样例)

缥帙各舒散,前后互相逾。这篇文章主要讲述第10天:apply和callbind函数作为参数返回值使用闭包递归的样例相关的知识,希望能为你提供帮助。
apply和callapply和call都可以改变this的指向
函数的调用,改变this的指向
函数名字.apply(对象,[参数1,参数2,.....])
方法名字.apply(对象,[参数1,参数2,.....])
方法名字.call(对象,参数1,参数2,.....)
方法名字.call(对象,参数1,参数2,.....)
不同的地方:参数传递是方式不一样
只要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么久可以使用apply或者call的方法改变this的指向
apply和call方法实际上并不在函数这个实例对象汇总,而是在Function的prototype中

< !DOCTYPE html> < html lang=" en" > < head> < meta charset=" UTF-8" > < meta name=" viewport" content=" width=device-width, initial-scale=1.0" > < meta http-equiv=" X-UA-Compatible" content=" ie=edge" > < title> Document< /title> < script> /* apply和call都可以改变this的指向 函数的调用,改变this的指向 */ function f1(x,y){ console.log((x+y)+" ======" +this); return " 这是函数的返回值" ; } //apply和call调用 var r1 = f1.apply(null,[1,2]); //此时f1中的this是window console.log(r1); var r2 = f1.call(null,1,2); console.log(r2); console.log(" =============" ); //改变this的指向 var obj = { sex:' 男' }; //本来f1函数是window对象,但是传入obj之后,f1函数此时就是obj对象的 var r1 = f1.apply(obj,[1,2]); //此时f1中的this是obj console.log(r1); var r2 = f1.call(obj,1,2); //此时f1中的this是obj console.log(r2); < /script> < /head> < body> < /body> < /html>

bind方法,是复制一份的时候,就改变指向bind是用来复制一份的
使用的语法
函数名字.bind(对象,参数1,参数2,......)----> 返回值就是赋值之后的这个函数
方法名字.bind(对象,参数1,参数2,......)----> 返回值就是赋值之后的这个方法
function f1(x,y){ console.log(x+y+" ========" +this.age); } //复制一份的时候,把参数传入f1函数中,null默认就是this,默认就是window //var ff= f1.bind(null,10,20); //ff(); // var ff= f1.bind(null); // ff(10,20); function Person(age){ this.age=age } var per = new Person(1800); var ff = f1.bind(per,100,200); ff();

函数作为参数使用
< !DOCTYPE html> < html lang=" en" > < head> < meta charset=" UTF-8" > < meta name=" viewport" content=" width=device-width, initial-scale=1.0" > < meta http-equiv=" X-UA-Compatible" content=" ie=edge" > < title> Document< /title> < script> function f1(fn){ console.log(" f1的函数" ); fn(); //此时fn当成一个函数来使用的 }; //传入匿命函数 f1(function(){ console.log(" 我是匿命函数" ); }) //命名函数 function f2(){ console.log(" f2的函数" ); } f1(f2); //函数作为参数的时候,如果是命名函数,那么传入命名函数的名字,没有括号 function f3(fn){ setInterval(function(){ console.log(" 定时器开始" ); fn(); console.log(" 定时器结束" ); },1000) } f3(function(){ console.log(" 中间" ); }) < /script> < /head> < body> < /body> < /html>

数组排序
var arr = [99,10,100,30,50,60,20,1] //排序--函数作为参数使用,匿命函数作为sort方法的参数使用, //那么此时的匿命函数中有两个参数 arr.sort(function(obj1,obj2){ if(obj1> obj2){ return 1; } else if(obj1==obj2){ return 0; }else{ return -1; } }) console.log(arr); //字符串排序 var arr2 = [" aa-2" ," aa-1" ," ab-2" ," af-1" ," ac-1" ] arr2.sort(function(a,b){ if(a> b){ return 1; }else if(a==b){ return 0 }else{ return -1 } }) console.log(arr2);

排序功能实现
< !DOCTYPE html> < html lang=" en" > < head> < meta charset=" UTF-8" > < meta name=" viewport" content=" width=device-width, initial-scale=1.0" > < meta http-equiv=" X-UA-Compatible" content=" ie=edge" > < title> Document< /title> < script> //排序,每个文件都有名字、大小、时间,可以按照某个属性的值进行排序 //三部电影,电影有名字,大小,上映时间 function File(name,size,time){ this.name = name; this.size = size; this.time = time; } var f1 = new File(" haha.avi" ," 500M" ," 1997-12-10" ); var f2 = new File(" jjj.avi" ," 200M" ," 2017-12-10" ); var f3 = new File(" zzz.avi" ," 100M" ," 2007-12-10" ); var arr = [f1,f2,f3]; //定义一个函数,定义传入要排序的属性 function fn(attr){ //函数作为返回值 return function getSort(a,b){ if(a[attr]> b[attr]){ return 1; }else if(a[attr]==b[attr]){ return 0; }else{ return -1; } } } //声明传入 var ff = fn(" time" ); //函数作为参数 arr.sort(ff); //循环遍历 for(var i = 0; i < arr.length; i++){ console.log(arr[i].name+" ====" +arr[i].size+" =====" +arr[i].time); }< /script> < /head> < body> < /body> < /html>

闭包闭包的概念:函数a中,有一个函数b,函数b中可以访问函数a中定义的变量或者是数据,此时形成闭包(这句话不严谨)
闭包的作用:缓存数据,延长作用域链
闭包的优点和缺点:缓存数据
闭包的模式:函数模式的闭包、对象模式的闭包
闭包的应用:
//函数模式的闭包 function f1(){ var num = 10; //函数声明 function f2(){ console.log(num); } //函数调用 f2() } f1(); //对象模式的闭包 function f3(){ var num =10; var obj = { age:num } console.log(obj.age); } f3();

闭包案例---点赞应用
< !DOCTYPE html> < html lang=" en" > < head> < meta charset=" UTF-8" > < meta name=" viewport" content=" width=device-width, initial-scale=1.0" > < meta http-equiv=" X-UA-Compatible" content=" ie=edge" > < title> Document< /title> < style> ul{ list-style: none; } li{ float: left; padding-left: 20px; position: relative; } img{ height: 300px; width: 200px; } input{ position: absolute; left: 100px; } < /style> < /head> < body> < ul> < li> < img src=https://www.songbingjia.com/android/" images/1_small.png" > < br/> < input type=" button" value=" 赞(1)" > < /li> < li> < img src=" images/2_small.png" > < br/> < input type=" button" value=" 赞(1)" > < /li> < li> < img src=" images/3_small.png" > < br/> < input type=" button" value=" 赞(1)" > < /li> < li> < img src=" images/4_small.png" > < br/> < input type=" button" value=" 赞(1)" > < /li> < /ul> < script> //获取元素 function my$(tagName){ return document.getElementsByTagName(tagName); } //闭包缓存数据 function getNumber(){ var value = 2; return function(){ this.value = " 赞(" +(value++)+" )" } } var inputs = my$(" input" ); //记得要写在页面加载后或者文档后for(var i = 0 ; i < inputs.length; i++){inputs[i].onclick=getNumber(); }< /script> < /body> < /html>

沙箱例子
< !DOCTYPE html> < html lang=" en" > < head> < meta charset=" UTF-8" > < meta name=" viewport" content=" width=device-width, initial-scale=1.0" > < meta http-equiv=" X-UA-Compatible" content=" ie=edge" > < title> Document< /title> < script> (function(){ var str = " 沙箱是啥呢" ; console.log(str); })(); < /script> < /head> < body> < div> sthis is sanbox< /div> < div> sthis is sanbox< /div> < div> sthis is sanbox< /div> < script> var getTag = 100; var objDiv = 200; //放到()()沙箱中就不会影响到 (function(){ function getTag(tagName){ return document.getElementsByTagName(tagName); } var objDiv = getTag(" div" ); for(var i = 0; i < objDiv.length; i++){ objDiv[i].style.border = " 2px solid pink" ; } })(); < /script> < /body> < /html>

递归函数中调用函数自己,此时就是递归,递归一定要有结束条件
递归简单解释
var i = 0; function f1(){ //如果小于5就给执行 i++; if(i< 5){ f1() } console.log(" 从前有座山,山里有座庙,庙里有个和尚" ); } f1();

递归例子
< !DOCTYPE html> < html lang=" en" > < head> < meta charset=" UTF-8" > < meta name=" viewport" content=" width=device-width, initial-scale=1.0" > < meta http-equiv=" X-UA-Compatible" content=" ie=edge" > < title> Document< /title> < script> //求n个数字的和,计算机1+2+3+4+5 var sum = 0; for(var i = 0; i < = 5; i++){ sum+=i; } console.log(sum); //传入x function getSum(x){ //x=1时返回1 if(x==1){ return 1; } //递归时 x传入加上返回的x-1数一直到结束条件 return x+getSum(x-1); } console.log(getSum(5)) /* 执行过程: 执行getSum(5)----> 进入函数,此时x是5,执行的是5+getSum(4),此时代码等待 此时5+getSum(4),代码先不进行计算,先执行getSum(4),进入函数, 执行的是4+getSum(3)...一直到getSum(1),执行到x==1 return 1, 此时getSum(1)的结果是1,开始向外走出去 2+getSum(1)此时的结果是:2+1 ... ... ... 结果:15*/ < /script> < /head> < body> < /body> < /html>

【第10天(apply和callbind函数作为参数返回值使用闭包递归的样例)】执行过程图
第10天(apply和callbind函数作为参数返回值使用闭包递归的样例)

文章图片

递归案例:求一个数字各个位数上数字的和 123=====1+2+3
//递归案例:求一个数字各个位数上数字的和123=====1+2+3 function getEverySum(x){ if(x< 10){ return x; } //获取的是这个数字的个位数 return x%10+getEverySum(parseInt(x/10)); } console.log(getEverySum(1234));


    推荐阅读