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、函数作为参数、返回值使用、闭包、递归的样例的更多相关文章

  1. python函数基础-参数-返回值-注释-01

    什么是函数 函数就是有特定功能的工具 # python中有内置函数(python解释器预先封装好的)与自定义函数(用户自定义封装的)之分 为什么要用函数 # 可以减少代码冗余,增加代码复用性 # 使代 ...

  2. python函数1_参数,返回值和嵌套

    函数 将重复的代码,封装到函数,只要使用直接找函数 函数可以增强代码的模块化和提高代码的重复利用率 函数的定义和调用 格式 def 函数名([参数,参数...]): 函数体 定义函数 import r ...

  3. 关于fork( )函数父子进程返回值的问题

    fork()是linux的系统调用函数sys_fork()的提供给用户的接口函数,fork()函数会实现对中断int 0x80的调用过程并把调用结果返回给用户程序. fork()的函数定义是在init ...

  4. linux shell自定义函数(定义、返回值、变量作用域)介绍

    http://www.jb51.net/article/33899.htm linux shell自定义函数(定义.返回值.变量作用域)介绍 linux shell 可以用户定义函数,然后在shell ...

  5. 函数指针的返回值是指针数组,数组里放的是int;函数指针的返回值是指针数组,数组里放的是int指针

    函数指针的返回值是指针数组,数组里放的是int 函数指针的返回值是指针数组,数组里放的是int指针 #include <stdio.h> #include <stdlib.h> ...

  6. 9 - Python函数定义-位置参数-返回值

    目录 1 函数介绍 1.1 为什么要使用函数 1.2 Python中的函数 2 函数的基本使用 3 函数的参数 3.1 参数的默认值 3.2 可变参数 3.2.1 可变位置传参 3.2.2 可变关键字 ...

  7. python开发初识函数:函数定义,返回值,参数

    一,函数的定义 1,函数mylen叫做函数名 #函数名 #必须由字母下划线数字组成,不能是关键字,不能是数字开头 #函数名还是要有一定的意义能够简单说明函数的功能 2,def是关键字 (define) ...

  8. [Golang]-3 函数、多返回值、变参、闭包、递归

    // test01 project main.go package main import ( "fmt" ) // 单返回值的函数 func plus(a int, b int) ...

  9. 【C语言入门教程】5.1 函数说明 与 返回值

    C 语言是结构化语言,它的主要结构成分是函数.函数被作为一种构件,用以完成程序中的某个具体功能.函数允许一个程序的各个任务被分别定义和编码,使程序模块化.本章介绍 C 语言函数的设计,如何用函数分解程 ...

  10. C++ 需要返回值的函数却没有返回值的情况 单例模式

    昨天在看前些天写的代码,发现一个错误. #include <iostream> using namespace std; class singleton { public: static ...

随机推荐

  1. AHOI2012 信号塔 | 最小圆覆盖模板

    题目链接:戳我 最小圆覆盖. 1.枚举第一个点,考虑当前圆是否包含了这个点,如果没有,则把圆变成以这个点为圆心,半径为0的圆. 2.枚举第二个点,考虑圆是否包含了这个点,如果没有,则把圆变成以这两个点 ...

  2. docker pull manifest unknown blob errors

    问题:docker pull manifest unknown blob errors 原因:公司网络是代理模式,所以我的 docker 服务配置成proxy模式: [root@localhost ~ ...

  3. JAVA特性一:封装

    封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. 封装概念详解:封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口. 面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完 ...

  4. TOJ1398正方形的编成 或者 POJ2362

    #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> ...

  5. “全栈2019”Java多线程第八章:放弃执行权yield()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. thinkphp3搜索结果分页

    公司的办公室搬到武昌,办公室水不好喝 还是乐百氏 娃哈哈的水我们oa用的tp3的一套oa,现在boss要求按状态 和类型(2个维度)来搜索案子 数量多,用 分页注意到初始的表单 input的name ...

  7. Create Index using NEST .NET

    Hello Guys, I have a doubt about how create index using NEST .NET. I created every fields in my C# m ...

  8. [转]NSProxy实现AOP方便为ios应用实现异常处理策略

    [转载自:http://blog.csdn.net/yanghua_kobe/article/details/8395535] 前段时间关注过objc实现的AOP,在GitHub找到了其中的两个库:A ...

  9. .net core webapi 使用过滤器。

    过滤器一般用于权限校验.日志处理... 一:ActionFilterAttribute过滤器. 1:建一个类,继承于ActionFilterAttribute抽象类. public class Log ...

  10. 认识CSS中精灵技术(sprite)和滑动门

    前端之HTML,CSS(十) 精灵技术与精灵图 精灵技术本质 精灵技术是一种处理网页背景图像的方式,实质是将小的背景图片拼接到一张大的背景图像上.拼接成的大图被称为精灵图.浏览器打开网页时,每一个图片 ...