一道优雅面试题分析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 相关文章推荐
使用onbeforeunload属性后的副作用
Mar 08 Javascript
[原创]后缀就扩展名为js的文件是什么文件
Dec 06 Javascript
比较搞笑的js陷阱题
Feb 07 Javascript
基于jquery实现图片广告轮换效果代码
Jul 07 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
Feb 11 Javascript
JavaScript加入收藏夹功能(兼容IE、firefox、chrome)
May 05 Javascript
JavaScript编写连连看小游戏
Jul 07 Javascript
javascript实现起伏的水波背景效果
May 16 Javascript
超全面的JavaScript开发规范(推荐)
Jan 21 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
Mar 30 Javascript
vue+element实现表格新增、编辑、删除功能
May 28 Javascript
js遍历详解(forEach, map, for, for...in, for...of)
Aug 28 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 选项及相关信息函数库
2006/12/04 PHP
PHP 文件上传源码分析(RFC1867)
2009/10/30 PHP
php实现的验证码文件类实例
2015/06/18 PHP
php+ajax实现仿百度查询下拉内容功能示例
2017/10/20 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
javascript在一段文字中的光标处插入其他文字
2007/08/26 Javascript
EasyUI中的tree用法介绍
2011/11/01 Javascript
jQuery对Select的操作大集合(收藏)
2013/12/28 Javascript
javascript动态控制服务器控件实例
2014/09/05 Javascript
JQuery中上下文选择器实现方法
2015/05/18 Javascript
JavaScript中isPrototypeOf函数作用和使用实例
2015/06/01 Javascript
MVC Ajax Helper或Jquery异步加载部分视图
2015/11/29 Javascript
DOM操作和jQuery实现选项移动操作的简单实例
2016/06/07 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
原生JavaScript来实现对dom元素class的操作方法(推荐)
2017/08/16 Javascript
React Component存在的几种形式详解
2018/11/06 Javascript
超好用的jQuery分页插件jpaginate用法示例【附源码下载】
2018/12/06 jQuery
使用koa2创建web项目的方法步骤
2019/03/12 Javascript
微信小程序 setData 对 data数据影响问题
2019/04/18 Javascript
NodeJs实现简易WEB上传下载服务器
2019/08/10 NodeJs
python打开url并按指定块读取网页内容的方法
2015/04/29 Python
利用python微信库itchat实现微信自动回复功能
2017/05/18 Python
django创建自定义模板处理器的实例详解
2017/08/14 Python
基于Pandas读取csv文件Error的总结
2018/06/15 Python
浅谈Python中eval的强大与危害
2019/03/13 Python
一文了解python 3 字符串格式化 F-string 用法
2020/03/04 Python
Python3.7将普通图片(png)转换为SVG图片格式(网站logo图标)动起来
2020/04/21 Python
django下创建多个app并设置urls方法
2020/08/02 Python
美国演唱会订票网站:Ticketmaster美国
2017/10/05 全球购物
最耐用行李箱,一箱永流传:Briggs & Riley(全球终身保修)
2017/12/07 全球购物
广告学专业推荐信范文
2013/11/23 职场文书
北京英语导游词
2015/02/12 职场文书
以权谋私检举信范文
2015/03/02 职场文书
Mysql中一千万条数据怎么快速查询
2021/12/06 MySQL
Python中的协程(Coroutine)操作模块(greenlet、gevent)
2022/05/30 Python
MySQL远程无法连接的一些常见原因总结
2022/09/23 MySQL