JavaScript入门-函数function(二)
JavaScript入门-函数function(二)
递归函数
- 什么是递归函数?
递归简单理解就是,在函数体里,调用自己。
//我们在求一个10的阶乘的时候,可能会这么做
//写一个循环
var total = 1
for(var i=10; i>=1; i++){
total *= i ;
}
这样的for循环简单直接。。。大家都会写
但是,我们可以写一个函数,递归调用
//递归函数
function jiecheng( n ){
if ( 1===n) return 1
return n*jiecheng(n-1)
}
//调用递归函数
var total = jiecheng(10)
ps:两种不同的方法,虽然结果都相同,但是还是有区别的。递归并没有通过for循环遍历每一个数,而且代码量变少了,看起来有点高大上。
- 其实,在递归调用的时候,就是按照return的特定来执行的。因为return只有在遇到一个具体的值才会返回给调用者。
- 然后,在调用的时候,会有一个'栈'的数据结构(先进后出,后进先出),存储每一个调用的时状态,直到遇到一个能够有具体值的状态,就逐层往上返回给调用者,最终的值就是你想要的值。
递归的缺点:
- 每次调用自己的时候,其实一直都是在占用着内存,占用资源较大。
闭包
- 什么是闭包?
我们先来回顾一下,在es5里,用var定义的变量,不管是在代码块里定义,还是在for循环里的局部变量,我们都能够访问到这个变量,这就叫做全局变量。如果我们在一个函数里用var定义变量,就是一个局部变量了,只有内部可以使用。
//定义全局变量
var a =1;
//函数体定义变量
function fun(){
var b =1;
}
//代码块里定义变量
{
var c = 1
{
var d = 'rainbow'
}
}
//for函数里的变量
for( var i = 0 ; i<10 ;i++){
console.log(i)
}
console.log( a , c , d , i )//1 1 "rainbow" 10
console.log(b)//error
ps:上面代码可以看出来,在JavaScript里,除了方法体内的变量未局部变量,其他的都是全局变量,那如果我们想要访问函数里面的变量该怎么办呢??
这个时候,我们就要用到闭包了。
- 在函数内自定义一个方法,返回函数定义的局部变量。
- 调用的时候,我们先调用外层的函数,得到的是一个函数体,然后再一次调用,就能够获取到outer的内部成员的变量了。
function outer(){
var num = 10;
funtion inner(){
console.log(num)
}
return inner;
}
var fun = outer()
fun()//10
或者
function outer() {
var age = 20;
return function () {//匿名函数
return age;
}
}
var age1 = outer();
console.log(age1())//20
总结:闭包,就是在函数内部定义一个函数,把function里私有的属性,通过这个内部函数返回给了外面。
特点:
- 通过闭包可以读取函数内部的变量
- 每一次调用最外层的方法,实际都是重新开辟一块内存空间., 因为返回的inner方法没有关闭,一直占用着内存,我们可以手动关闭 outer = null
- 在outer里定义的变量,通过闭包获取到的成员变量,其实都是静态static变量,正如第2点所说,变量还是存在内存中,并没有主动释放。
闭包的缺点:
- 和递归类似,一直占用着内存资源,可能导致内存泄漏。
可能我自己讲的不够全,大家看看大佬的文章
彻底理解闭包
https://www.cnblogs.com/itjeff/p/10106855.html
阮一峰老师的
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
回调函数
回调函数有个比较逼格的名字——句柄。我们只要知道有这么个官方的叫法就行,以后面试或者交流的时候,也不至于听不懂这是啥东西。
简单理解就是,把一个函数当作参数。那么这个函数就是回调函数。
那为啥叫回调呢?
那是因为你执行一个方法时候,还不能够预期或者确定会有什么样的结果,必须得再回过头来调用这个函数(也就是传的参数),得到具体的结果。
function fun(callback){
console.log(callback)
}
//把一个方法当作参数
function say (value) {
alert(value);
}
alert(say);
alert(say('hi js.'));
ps:回调函数应用场景多用在使用 js 写组件时,尤其是组件的事件很多都需要回调函数的支持。
内置函数
其实,我们js的类库提供了很多的函数,比如经常用的console.log(),alert()等等。但是在还未学习面向对象之前,主要来了解两个内置函数,定时器setTimeout和setInterval
//使用方法
setTimeout(callback,delay);
setInterval(callback,delay);
function callback(){
console.log('rainbow');
}
var delay = 1*1000;
//解释一下
callback:定时器要执行的方法
delay:定时器执行方法的间隔。单位ms毫秒
setTimeout、setInterval区别
- setTimeout 只能执行一次,而setInterval一直执行。
那么如何停止定时器呢?
每个定时器都会返回一个定时器id,这个id在线程池中存着,我们接收他的id,然后清除
//接收id
var id1 = setTimeout(callback,delay);
var id2 = setInterval(callback,delay);
//关闭定时器
clearTimeout(id1)
clearInterval(id2)
ps:
- 关闭定时器,clearTimeout或者clearInterval都可以关闭对方的id,因为他们共用一个定时器ID poor。
- delay这个参数,并不会很精确,因为这和时间片轮转有关。要想了解更多,可以去学习一下操作系统,进程和线程是什么。
其实,学习定时器的时候,我们就应该了解一下,js里只有单线程,而且理论是没有异步操作的,大家口中说的那是模拟异步,那么大家就需要了解一个叫做任务队列的东西。
说到这里,我们就来说三个任务,其实还有很多的:
- 渲染队列:比如浏览器的渲染,ie的hasLayout
- 事件队列:比如点击事件onclick
- 定时器队列:一定会等主程序执行完毕后再执行
这些都是有一定执行顺序的,渲染队列->事件队列->定时器队列,所以定时器这个玩意,就像个弃儿,凡事都要最后才能拥有,这也就知道为啥你给他设置delay时间的时候,不会那么精确了。
谢谢大家能读完这篇随笔,鄙人学识浅薄,很多地方讲的自认为不是很深入,也比较的俗,见谅见谅...
JavaScript入门-函数function(二)的更多相关文章
- Javascript常用方法函数收集(二)
Javascript常用方法函数收集(二) 31.判断是否Touch屏幕 function isTouchScreen(){ return (('ontouchstart' in window) || ...
- JavaScript入门学习之二——函数
在前一章中讲了JavaScript的入门语法,在这一章要看看函数的使用. 函数的定义 JavaScript中的函数和Python中的非常类似,只不过定义的方式有些不同,下面看看是怎么定义的 //定义普 ...
- javaScript的函数(Function)对象的声明(@包括函数声明和函数表达式)
写作缘由: 平时再用js写函数的时候,一般都是以惯例 function fn () {} 的方式来声明一个函数,在阅读一些优秀插件的时候又不免见到 var fn = function () {} 这种 ...
- 05.Javascript——入门函数
//定义函数的方法1 function abs(x) { if (x >= 0) { return x; } else { return -x; } } 上述abs()函数的定义如下: func ...
- JavaScript入门进阶(二)
JavaScript进阶入门(二) 转换为数字 使用parseInt() parseInt函数会先查看位置0处的字符,如果该位置不是有效数字,则将返回NaN,如果0处的字符是数字,则将查看位置1处的字 ...
- Javascript 回调函数理解---二娃子买肾机6
在Javascript中什么是回调函数,我认为简单来说就是把一个函数B作为参数传递给另一个函数A,在A函数中的一定时机调用函数B. 这里可以看出回调函数形成了一个闭包,它可以访问函数A中的活动对象. ...
- javascript的函数(二)
1. 函数的作用域 作用域是指变量的存在的范围.javascript中有两种作用域,一种是全局作用域,变量在整个程序中一直存在,另一种是函数作用域,变量只存在于函数体内部.在函数体外部声明的变量就是全 ...
- JavaScript系列----函数(Function)篇(4)
1.什么是函数? 在W3C中函数的定义是这么说的:函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. 诚然,从这种抽象的定义中我们得不到什么有价值的东西.下面,举例来列举出函数的几种定义 ...
- JavaScript中函数function fun(){}和 var fun=function(){}的区别
function fun(){} 和 var fun=function(){}的区别 标题有点长···· 废话少说,其实他们的主要区别就是"函数声明的提前行为". var fun= ...
随机推荐
- jenkins配置--上传代码,定时执行用例,发送测试报告
1.安装条件:jdk1.8以上的,百度jenkin进入官网--download ,根据需要的版本下载 2.jenkins概念:持续集成,jenkins开源属于插件式形式进行管理的,选择性的装插件,支持 ...
- mysql 查询 添加 删除 语句
1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数据的 d ...
- springmvc中使用文件下载功能
项目代码:https://github.com/PeiranZhang/springmvc-fileupload 使用文件下载步骤 对请求处理方法使用void或null作为返回类型,并在方法中添加Ht ...
- js上 九.多分支语句
9-3.if...else if ...else语句 多分支的if语句,多选一. 格式:
- 网站开发学习Python实现-Django学习-介绍(6.1.1)
@ 目录 1.MVT 2.ORM 关于作者 1.MVT 主要的目的是为了快速,简便的开发数据库驱动的网站,强调代码的复用,多个组件可以很方便以插件的方式服务于整个框架,采用的是MVT设计模式(差不多的 ...
- 302跳转导致的url劫持
介绍一个 网站监测工具:iis7网站监测IIS7网站监控工具可以做到提前预防各类网站劫持,并且是免费在线查询,适用于各大站长,政府网站,学校,公司,医院等网站.它可以做到24小时定时监控,同时它可 ...
- python一键搭建ftp服务
from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handlers import FTPHandler from pyf ...
- MVC中Autofac的使用
参考博文 https://www.cnblogs.com/liupeng/p/4806184.html https://blog.csdn.net/qq_37214567/article/detail ...
- ES6语法:class类,从了解到使用
前期提要: JavaScript 语言中,在使用类之前,生成实例对象的传统方法是通过使用构造函数. 一.构造函数: 定义:通过 new 函数名 来实例化对象的函数叫构造函数. 主要功能:为初 ...
- Listary效率快捷键
快捷键 打开搜索框快捷键: 双击Ctrl键 上一个项目:向上键 下一个项目:向下键/Tap 打开动作:Enter 属性窗口:Ctrl+O (查询)关键字 作用范围:搜索框 使用方法:命令+空格+关键字 ...