需求是这样的,从子节点寻找指定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. 数据流图——从软考真题中学画数据流图DFD

    文章目录 题目 画顶层图 画0层图 解题技巧 题目 建议将题目复制到word后与此文分屏查看.后面需要多次查看题目. 某高校欲开发一个成绩管理系统,记录并管理所有选修课程的学生的平时成绩和考试成绩, ...

  2. python爬虫-百度百科百名红通人员名单

    爬虫代码: import urllib.request import os, re from bs4 import BeautifulSoup import xlwt URL = "http ...

  3. Sublime text 2/3 [Decode error - output not utf-8] 完美解决方法

    原文链接 http://blog.csdn.net/bbdxf/article/details/25594703 [Decode error - output not utf-8]或者[Decode  ...

  4. 【转】Android总结篇系列:Activity生命周期

    [转]Android总结篇系列:Activity生命周期 Android官方文档和其他不少资料都对Activity生命周期进行了详细介绍,在结合资料和项目开发过程中遇到的问题,本文将对Activity ...

  5. 解决mysql for docker容器报错:Authentication plugin 'caching_sha2_password' cannot be loaded

    为图方便,懒得在mac上安装mysql了,一个是管理不方便,第二个是为了方便多机器同步开发环境.就使用docker安装了. 拉取mysql镜像 docker pull mysql 运行mysql实例 ...

  6. (PMP)第4章-----项目整合管理

    4.1 制定项目章程 输入 工具与技术 输出 1.商业文件 (商业论证,效益管理计划) 1.专家判断 1.项目章程 2.协议 2.数据收集 (头脑风暴,焦点小组,访谈) 2.假设日志 3.事业环境因素 ...

  7. [小结]InnoDB体系结构及工作原理

    参阅:<innodb存储引擎内幕>原创文章,会不定时更新,转发请标明出处:http://www.cnblogs.com/janehoo/p/7717041.html 一.概述: innod ...

  8. Thread,ThreadPool,Task

    线程分为前台和后台.比如我们直接new一个Thread这就是前台线程. 前台线程一定会执行. 比如我们创建2个线程:1号,2号,同时执行,假设1号是主线程,1执行完了,依旧会等待2执行完成,整个程序才 ...

  9. Node.js创建本地简易服务器

    创建简易的本地服务器 安装node.js 在项目下,通过npm init -y创建package.json文件 通过npm install mime --save加载mime插件 创建server.j ...

  10. Unity3D在移动平台下加载AssetBundle导致Shader效果不正确的问题

    这个问题,主要还是在移动平台下开发导致的. 在编辑器里调试加载AB时会导致Shader效果不正确的原因,主要还是编辑器下加载以IOS或是ANDROID平台打包的AB它所使用的shader已经编译成对应 ...