第10天:apply和call、bind、函数作为参数、返回值使用、闭包、递归的样例
apply和call
apply和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="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>
执行过程图

递归案例:求一个数字各个位数上数字的和 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));
第10天:apply和call、bind、函数作为参数、返回值使用、闭包、递归的样例的更多相关文章
- python函数基础-参数-返回值-注释-01
什么是函数 函数就是有特定功能的工具 # python中有内置函数(python解释器预先封装好的)与自定义函数(用户自定义封装的)之分 为什么要用函数 # 可以减少代码冗余,增加代码复用性 # 使代 ...
- python函数1_参数,返回值和嵌套
函数 将重复的代码,封装到函数,只要使用直接找函数 函数可以增强代码的模块化和提高代码的重复利用率 函数的定义和调用 格式 def 函数名([参数,参数...]): 函数体 定义函数 import r ...
- 关于fork( )函数父子进程返回值的问题
fork()是linux的系统调用函数sys_fork()的提供给用户的接口函数,fork()函数会实现对中断int 0x80的调用过程并把调用结果返回给用户程序. fork()的函数定义是在init ...
- linux shell自定义函数(定义、返回值、变量作用域)介绍
http://www.jb51.net/article/33899.htm linux shell自定义函数(定义.返回值.变量作用域)介绍 linux shell 可以用户定义函数,然后在shell ...
- 函数指针的返回值是指针数组,数组里放的是int;函数指针的返回值是指针数组,数组里放的是int指针
函数指针的返回值是指针数组,数组里放的是int 函数指针的返回值是指针数组,数组里放的是int指针 #include <stdio.h> #include <stdlib.h> ...
- 9 - Python函数定义-位置参数-返回值
目录 1 函数介绍 1.1 为什么要使用函数 1.2 Python中的函数 2 函数的基本使用 3 函数的参数 3.1 参数的默认值 3.2 可变参数 3.2.1 可变位置传参 3.2.2 可变关键字 ...
- python开发初识函数:函数定义,返回值,参数
一,函数的定义 1,函数mylen叫做函数名 #函数名 #必须由字母下划线数字组成,不能是关键字,不能是数字开头 #函数名还是要有一定的意义能够简单说明函数的功能 2,def是关键字 (define) ...
- [Golang]-3 函数、多返回值、变参、闭包、递归
// test01 project main.go package main import ( "fmt" ) // 单返回值的函数 func plus(a int, b int) ...
- 【C语言入门教程】5.1 函数说明 与 返回值
C 语言是结构化语言,它的主要结构成分是函数.函数被作为一种构件,用以完成程序中的某个具体功能.函数允许一个程序的各个任务被分别定义和编码,使程序模块化.本章介绍 C 语言函数的设计,如何用函数分解程 ...
- C++ 需要返回值的函数却没有返回值的情况 单例模式
昨天在看前些天写的代码,发现一个错误. #include <iostream> using namespace std; class singleton { public: static ...
随机推荐
- 「ZJOI 2010」 排列计数
题目链接 戳我 \(Solution\) 其实我们可以发现这题等价于让你求: 用\(1\)~\(n\)的数组成一个完全二叉树使之满足小根堆性质的方案数 于是我们可以考虑\(dp\) 假设我们现在在\( ...
- 初识阿里开源诊断工具Arthas
上个月,阿里开源了一个名为Arthas的监控工具.恰逢近期自己在写多线程处理业务,由此想到了一个问题. 如果在本机开发调试,IDE可以看到当前的活动线程,例如IntelliJ IDEA,线程是运行还是 ...
- SQL语句优化 (二) (53)
接上一部分 (4)如果不是索引列的第一部分,如下例子:可见虽然在money上面建有复合索引,但是由于money不是索引的第一列,那么在查询中这个索引也不会被MySQL采用. mysql> exp ...
- oracle根据四位年周取当周周一的日期函数
create or replace function FUNC_GET_DATE_BY_WEEK( theYearWeek IN VARCHAR2)return date is normalDate ...
- MySQL 跟中文相关
convert ()
- jquery源码解析:jQuery数据缓存机制详解1
jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...
- SQLServer 的存储过程与java交互
一. 存储过程简介 Sql Server的存储过程是一个被命名的存储在服务器上的Transacation-Sql语句集合,是封装重复性工作的一种方法,它支持用户声明的变量.条件执行和其他强大的编程 ...
- multiprocessor(中)
一.进程同步(锁) 通过之前的学习,我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发处理,他们之间的运行没有顺序,一旦开启也不受我们控制.尽管并发编程让我们能更加充分的利用IO资源,但 ...
- SaltStack Pillar 详解
简介 grains用于存储静态不易变更的数据,而pillar一般用于存储动态, 敏感的数据,通过minion和master设置或获取grains信息,而pillar信息只能在master端配置,在到m ...
- IDEA自动生成TestNG的testng.xml的插件
某地方见到的,自己实际操作一遍,记录一下.方便以后查询. 下载Create TestNG XML 插件,重启IDEA即可. 重启idea,新建Maven项目. pom.xml增加依赖 <depe ...