需求是这样的,从子节点寻找指定className的父节点,一开始就想到递归(笨!),Dom结构如下:

<div class="layer_1">
<div class="layer_2">
<div class="layer_3">
<div id="layer_4"></div>
</div>
</div>
</div>

先通过id获得layer_4的div,然后逐层向上寻找最外层的layer_1,一开始我试图用如下递归获取:

 function getNode(){
var child = $("#layer_4");
var parent = getParent(child);
return parent;
} function getParent(el){
var result;
result = el.parentNode;
if(!el || el === document.documentElement || el.parentNode === document.documentElement){
return;
}else if(result && result.className === "layer_1"){
return result;
}else{
getParent(result);
}
return result;
} getNode(); //undefined

结果返回的是undefined!

本来是一最基本的递归,为什么会出现这种结果?

其实修改这个问题很简单,目前我只想到一个办法:将result声明为全局变量!

当然这个方法的缺点是造成了memory leak,折中的解决办法是在获取到result后将result =null。

可能有朋友看到这里就已经知道这个问题的原因了,那就是:JavaScript中function的作用域问题-闭包!下面详细解释一下。

如果按照上面的写法,

1、每次递归调用getParent()方法是都会声明一个局部变量result,同时因为闭包的缘故,每次的gerParent()的运行作用域又保留着上次getParent()的作用域,所以每次都会覆盖上层同名的result,作为一个当前函数域的局部变量;

2、当找到layer_1后,result更新,return result得到了我们想要的结果,跳出本次函数域,进入上层函数域,但此时的上层函数域中result并未更新(因为被下层函数域的同名result屏蔽了),所以此时最外层的result仍然是undefined!

所以最终将的到undefined!

这个问题同样引出了以前遇到的关于return的bug,当时把return想象的太强大了,以为return会跳出整条作用域链,上述问题证明了return只能跳出当前作用域,以后注意!

补充:谢谢亮哥的指导,用全局变量解决确实是最笨的法子了,以下是改进办法:

function getParent(el){
var result;
result = el.parentNode;
if(!el || el === document.documentElement || el.parentNode === document.documentElement){
return;
}else if(result && result.className === "layer_1"){
return result;
}else{
return getParent(result);
}
}

在每次递归调用时用return跳出当前函数域,之后进入下层函数时result获取后直接返回,而不用回到最外层函数域。避免了全局变量,同时优化了递归运算。

JavaScript递归中的作用域问题的更多相关文章

  1. 【授课录屏】JavaScript高级(IIFE、js中的作用域、闭包、回调函数和递归等)、MySQL入门(单表查询和多表联查)、React(hooks、json-server等) 【可以收藏】

    一.JavaScript授课视频(适合有JS基础的) 1.IIFE 2.js中的作用域 3.闭包 4.表达式形式函数 5.回调函数和递归 资源地址:链接:https://pan.baidu.com/s ...

  2. JavaScript中的作用域

    很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...

  3. 浅谈javascript中的作用域

    首先说明一下:Js中的作用域不同于其他语言的作用域,要特别注意     JS中作用域的概念: 表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境.Javascript的作 ...

  4. 【翻译】JavaScript中的作用域和声明提前

    原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译开始=== 你知道下面的JavaScript脚本执 ...

  5. JavaScript中的作用域和声明提前

    [翻译]JavaScript中的作用域和声明提前 原文:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ===翻译 ...

  6. 认识javascript中的作用域和上下文

    javascript中的作用域(scope)和上下文(context)是这门语言的独到之处,这部分归功于他们带来的灵活性.每个函数有不同的变量上下文和作用域.这些概念是javascript中一些强大的 ...

  7. javascript学习中自己对作用域和作用域链理解

    在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域?  从字面上理解就是起 ...

  8. 漫谈JavaScript中的作用域(scope)

    什么是作用域 程序的执行,离不开作用域,也必须在作用域中才能将代码正确的执行. 所以作用域到底是什么,通俗的说,可以这样理解:作用域就是定义变量的位置,是变量和函数的可访问范围,控制着变量和函数的可见 ...

  9. 深入理解JavaScript中的作用域和上下文

    介绍 JavaScript中有一个被称为作用域(Scope)的特性.虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,我会尽我所能用最简单的方式来解释作用域.理解作用域将使你的代码脱颖而出,减 ...

随机推荐

  1. 【第一次作业】&&软件工程大一班---甘昀

    这个作业属于哪个课程: <课程的链接点这里>  这个作业要求在哪里: <作业要求的链接点这里> 我在这个课程的目标是:  学会软件开发的流程和思想 这个作业在哪个具体方面帮助我 ...

  2. Python 的经典设计格言,格言来源于 Python 但不限于 Python

    The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Si ...

  3. Open quote is expected for attribute "{1}" associated with an element type "column".

    这个的错误的意思很简单:就是自己的配置文件是否缺少""号

  4. Golang之路【目录】

    我正在写一套使用Golang全栈开发的教程,名字暂叫“Golang之路”,希望大家多提建议. 目录如下: Golang之路[第一篇]:Golang简介和入门Golang之路[第二篇]:Golang基础 ...

  5. 口试Linq题

    LINQ to SQL与IQueryable 理解IQueryable的最简单方式就是,把它看作一个查询,在执行的时候,将会生成结果序列. LINQ to Object和LINQ to SQL有何区别 ...

  6. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  7. tp5 数据库

    连接数据库: 在config下面的database.php里. 查找数据: halt(Db::name('studys')->column('name','age')); 也可以用find fi ...

  8. redis学习-散列表常用命令(hash)

    redis学习-散列表常用命令(hash)   hset,hmset:给指定散列表插入一个或者多个键值对 hget,hmget:获取指定散列表一个或者多个键值对的值 hgetall:获取所欲哦键值以及 ...

  9. ES6使用fetch请求数据

    ie是完全不支持fetch的. fetch(url,{method:"get/post"}).then(res=>{   }) 如果请求返回的status是200,body是 ...

  10. Chrome 的 PNaCl 还活着么?

    WebAssembly Migration Guide Given the momentum of cross-browser WebAssembly support, we plan to focu ...