一道优雅面试题分析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 相关文章推荐
简单的jquery拖拽排序效果实现代码
Sep 20 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
Mar 03 Javascript
jQuery中:first-child选择器用法实例
Dec 31 Javascript
JavaScript中使用Object.prototype.toString判断是否为数组
Apr 01 Javascript
极力推荐10个短小实用的JavaScript代码段
Aug 03 Javascript
jquery判断类型是不是number类型的实例代码
Oct 07 Javascript
vue.js学习之递归组件
Dec 13 Javascript
JavaScript中in和hasOwnProperty区别详解
Aug 04 Javascript
微信小程序picker组件简单用法示例【附demo源码下载】
Dec 05 Javascript
JS中原始值和引用值的储存方式示例详解
Mar 23 Javascript
微信小程序云开发之新手环境配置
May 16 Javascript
微信小程序自定义底部弹出框动画
Nov 18 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+jquery编码方面的一些心得(utf-8 gb2312)
2010/10/12 PHP
PHPMYADMIN导入数据最大为2M的解决方法
2012/04/23 PHP
php全局变量和类配合使用深刻理解
2013/06/05 PHP
PHP封装的一个支持HTML、JS、PHP重定向的多功能跳转函数
2014/06/19 PHP
php添加数据到xml文件的简单例子
2016/09/08 PHP
jQuery select的操作实现代码
2009/05/06 Javascript
jquery 注意事项与常用语法小结
2010/06/07 Javascript
利用javascript实现web页面中指定区域打印
2013/10/30 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
2014/09/28 Javascript
jquery中push()的用法(数组添加元素)
2014/11/25 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
2015/09/14 Javascript
js遍历map javaScript遍历map的简单实现
2016/08/26 Javascript
微信小程序  生命周期详解
2016/10/27 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
jquery实现转盘抽奖功能
2017/01/06 Javascript
jQuery中的一些小技巧
2017/01/18 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
js求数组中全部数字可拼接出的最大整数示例代码
2017/08/25 Javascript
JS使用iView的Dropdown实现一个右键菜单
2019/05/06 Javascript
JavaScript实现星级评价效果
2019/05/17 Javascript
layui关闭层级、简单监听的实例
2019/09/06 Javascript
转换layUI的数据表格中的日期格式方法
2019/09/19 Javascript
Vue插件之滑动验证码
2019/09/21 Javascript
基于javascript的无缝滚动动画实现2
2020/08/07 Javascript
[49:11]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第二场 12.20
2020/12/23 DOTA
Python 基于Twisted框架的文件夹网络传输源码
2016/08/28 Python
Python实现的简单计算器功能详解
2018/08/25 Python
详解CSS3中的box-sizing(content-box与border-box)
2019/04/19 HTML / CSS
Ann Taylor官方网站:美国最大的女性产品制造商之一
2016/09/14 全球购物
Lime Crime官网:美国一家主打梦幻精灵系的彩妆品牌
2019/03/22 全球购物
学校清明节活动总结
2014/07/04 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
参加招聘会后的感想
2015/08/10 职场文书
html+css实现赛博朋克风格按钮
2021/05/26 HTML / CSS
Java spring定时任务详解
2021/10/05 Java/Android
浅谈css清除浮动(clearfix和clear)的用法
2023/05/21 HTML / CSS