一道优雅面试题分析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 相关文章推荐
javascript 隐藏/显示指定的区域附HTML元素【legend】用法
Mar 05 Javascript
javascript+iframe 实现无刷新载入整页的代码
Mar 17 Javascript
一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)
Jun 02 Javascript
js 利用className得到对象的实现代码
Nov 15 Javascript
js和jquery中循环的退出和继续下一个循环
Sep 03 Javascript
Javascript闭包用法实例分析
Jan 23 Javascript
JS选项卡动态替换banner图片路径的方法
May 11 Javascript
Vue.js中数组变动的检测详解
Oct 12 Javascript
完美实现js焦点轮播效果(一)
Mar 07 Javascript
angularjs性能优化的方法
Sep 05 Javascript
JS实现将对象转化为数组的方法分析
Jan 21 Javascript
详解uniapp的全局变量实现方式
Jan 11 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
我的论坛源代码(四)
2006/10/09 PHP
php下封装较好的数字分页方法
2010/11/23 PHP
PHP缓存技术的多种方法小结
2012/08/14 PHP
解析php常用image图像函数集
2013/06/24 PHP
PHP HTTP 认证实例详解
2016/11/03 PHP
Yii2框架类自动加载机制实例分析
2018/05/02 PHP
tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】
2020/05/26 PHP
原生js ActiveXObject获取execl里面的值
2013/11/01 Javascript
js操作IE浏览器弹出浏览文件夹可以返回目录路径
2014/07/14 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
javascript实时显示北京时间的方法
2015/03/12 Javascript
javascript实现无缝上下滚动特效
2015/12/16 Javascript
JavaScript中Array的实用操作技巧分享
2016/09/11 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
2016/12/30 Javascript
bootstrap警告框使用方法解析
2017/01/13 Javascript
基于iScroll实现下拉刷新和上滑加载效果
2017/07/18 Javascript
使用axios实现上传图片进度条功能
2017/12/21 Javascript
微信小程序自定义prompt组件步骤详解
2018/06/12 Javascript
koa2的中间件功能及应用示例
2020/03/05 Javascript
Python语法快速入门指南
2015/10/12 Python
python将视频转换为全字符视频
2019/04/26 Python
python如何以表格形式打印输出的方法示例
2019/06/21 Python
Python urllib2运行过程原理解析
2020/06/04 Python
使用Keras 实现查看model weights .h5 文件的内容
2020/06/09 Python
如何教少儿学习Python编程
2020/07/10 Python
Python提取视频中图片的示例(按帧、按秒)
2020/10/22 Python
HTML高亮关键字的实现代码
2018/10/22 HTML / CSS
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
毕业生自荐书
2013/12/18 职场文书
我的动漫时代的创业计划书范文
2014/01/27 职场文书
数控专业自荐书范文
2014/03/16 职场文书
我爱我家教学反思
2014/05/01 职场文书
冬季安全检查方案
2014/05/23 职场文书
党员志愿者活动方案
2014/08/28 职场文书
关于远足的感想
2015/08/10 职场文书
Golang gRPC HTTP协议转换示例
2022/06/16 Golang