一道优雅面试题分析js中fn()和return fn()的区别


Posted in Javascript onJuly 05, 2016

在js中,经常会遇到在函数里调用其它函数的情况,这时候会有 fn() 这种调用方式,还有一种是 return fn() 这种调用方式,一些初学者经常会被这两种方式给绕晕了。这里用一个优雅的面试题来分析一下两种方式的不同之处。 

var i = 0;
function fn(){
 i++;
 if(i < 10){
 fn();
 }else{
 return i;
 }
}

var result = fn();
console.log(result);

这是一道隐藏了坑的面试题,看似很简单,大部分人可能想都不想就答出了10。而实际上运行可知打印出来的是 undefined。这道陷阱题很直观的体现出了前面所说的问题,当我们将执行fn的那一行修改为: 

var i = 0;
function fn(){
 i++;
 if(i < 10){
 return fn();
 }else{
 return i;
 }
}

var result = fn();
console.log(result);

这时,会发现打印出来的结果终于不负众望的是 10 了。

为什么这里加不加return区别会这么大? 

这里的主要原因很简单,JavaScript的函数都是有默认返回值的,如果函数结尾不写return,会默认返回undefined,这就是为什么在chrome的console控制台里,写代码经常下面会出现一行undefined的原因。 

再仔细看看这个例子,当i自增到9的时候,也就是倒数第二次递归调用fn的那一次,如果没有return,这一次执行完fn,会默认return undefined,而不会继续下一次递归了。当加上了 return,在这里则会继续最后一次递归,即i=10的时候,跳入else里面返回得到正确的10。 

说到这里,可以引申出一个更为经典的例子,著名的二分查找法: 

var mid = Math.floor((arr.length - 1) / 2);

function search(n, mid) {
 if (n > arr[mid]) {
 mid = Math.floor((mid + arr.length) / 2);
 return search(n, mid);
 } else if (n < arr[mid]) {
 mid = Math.floor((mid - 1) / 2);
 return search(n, mid);
 } else {
 return mid;
 }
}

var index = search(n, mid);
console.log(index);

二分查找法也是需要多次递归调用,很多新手在第一次实现这个算法的时候经常会犯的一个错误就是忘记在递归的函数前加上return,最后导致返回结果是undefined,这里的道理也和前面是类似的,不加return,会导致递归后,直接返回undefined,不会继续下一次递归。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
cssQuery()的下载与使用方法
Jan 12 Javascript
[全兼容哦]--实用、简洁、炫酷的页面转入效果loing
May 07 Javascript
javascript iframe编程相关代码
Dec 28 Javascript
javascript函数中参数传递问题示例探讨
Jul 31 Javascript
JavaScript显示表单内元素数量的方法
Apr 02 Javascript
JS拖动鼠标画出方框实现鼠标选区的方法
Aug 05 Javascript
基于JavaScript获取鼠标位置的各种方法
Dec 16 Javascript
基于Angularjs实现分页功能
May 30 Javascript
JavaScript ES6的新特性使用新方法定义Class
Jun 28 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
Jan 02 jQuery
浅谈如何通过node.js对数据进行MD5加密
May 16 Javascript
Js图片点击切换轮播实现代码
Jul 27 Javascript
JS实现环形进度条(从0到100%)效果
Jul 05 #Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 #Javascript
结合代码图文讲解JavaScript中的作用域与作用域链
Jul 05 #Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
Jul 05 #Javascript
Node.js实现文件上传
Jul 05 #Javascript
JavaScript数组方法大全(推荐)
Jul 05 #Javascript
JS与HTML结合使用marquee标签实现无缝滚动效果代码
Jul 05 #Javascript
You might like
使用php实现下载生成某链接快捷方式的解决方法
2013/05/07 PHP
PHP写的资源下载防盗链类分享
2014/05/12 PHP
跨浏览器的设置innerHTML方法
2006/09/18 Javascript
js滚动条回到顶部的代码
2011/12/06 Javascript
关于jquery css的使用介绍
2013/04/18 Javascript
jquery中map函数遍历数组用法实例
2015/05/18 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
2015/12/09 Javascript
jQuery插件支持同一页面被多次调用
2016/02/14 Javascript
JS留言功能的简单实现案例(推荐)
2016/06/23 Javascript
jQuery mobile的header和footer在点击屏幕的时候消失的解决办法
2016/07/01 Javascript
详解前后端分离之VueJS前端
2017/05/24 Javascript
用js实现before和after伪类的样式修改的示例代码
2017/09/07 Javascript
一个Vue页面的内存泄露分析详解
2018/06/25 Javascript
vue项目打包后打开页面空白解决办法
2018/06/29 Javascript
vue2.0 如何在hash模式下实现微信分享
2019/01/22 Javascript
解决layui页面按钮点击无反应,也不报错的问题
2019/09/29 Javascript
VUEX采坑之路之获取不到$store的解决方法
2019/11/08 Javascript
JavaScript实现栈结构Stack过程详解
2020/03/07 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
Vue-cli 移动端布局和动画使用详解
2020/08/10 Javascript
vue实现顶部菜单栏
2020/11/08 Javascript
JavaScript实现点击出现子菜单效果
2021/02/08 Javascript
Python学习之asyncore模块用法实例教程
2014/09/29 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
python装饰器-限制函数调用次数的方法(10s调用一次)
2018/04/21 Python
python实现连连看辅助(图像识别)
2020/03/25 Python
浅谈python之自动化运维(Paramiko)
2020/01/31 Python
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
来自世界上最好大学的在线课程:edX
2018/10/16 全球购物
波兰在线杂货店:Polski Koszyk
2019/11/02 全球购物
专业实习自我鉴定
2013/10/29 职场文书
毕业生自我鉴定
2013/11/05 职场文书
心得体会怎么写
2013/12/30 职场文书
2014年党员承诺书范文
2014/05/20 职场文书
部门2015年度工作总结
2015/04/29 职场文书
Sql Server 行数据的某列值想作为字段列显示的方法
2022/04/20 SQL Server