缥帙各舒散,前后互相逾。这篇文章主要讲述第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函数作为参数返回值使用闭包递归的样例)】执行过程图
文章图片
递归案例:求一个数字各个位数上数字的和 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));
推荐阅读
- 安卓开发(UI组件-布局管理器和文本显示)
- Android-Kotlin简单计算器功能
- Android---16进制与字节数组
- Android-Kotlin-配置/入门
- 挖矿交易所开发,搭建币币交易系统app
- Android学习之基础知识十四 — Android特色开发之基于位置的服务
- Android的几种弹出框
- Android防止活动被回收而丢失数据
- 组件化封装思想实战Android App