Seasons123 / blog-FE

web前端相关issue is my blog :lollipop:
2 stars 0 forks source link

老生常谈的闭包问题 #18

Open Seasons123 opened 7 years ago

Seasons123 commented 7 years ago

【问题1】有这样的几个元素,期望点击每一个,弹出对应的下标

<p>0</p>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>

[解析] 一般我们的回答可能循环绑定事件,然后对应输出,方法大概7-8种或许更多,先看错误例子.

var arr = document.getElementsByTagName('p');
for(var i = 0;i<arr.length;i++){
   arr[i].onclick = function(){
        alert(i);
   }
}

这样的输出结果,肯定出来的都是4喽(原因见笔记《blue cat》笔记3.5.2.4循环中的闭包,《es6标准入门》p10和p13也有解释)。这可不是我们想要的。改造一下~

var arr = document.getElementsByTagName('p');
for(var i = 0;i<arr.length;i++){
    (function(){
       var temp = i;
       arr[i].onclick = function () {
            alert(i);
       }
    })();
}

可能你用过es6,你想到了用let来替代var,再改造一下

var arr = document.getElementsByTagName('p');
for(let i = 0;i<arr.length;i++){
    arr[i].onclick = function(){
        alert(i)
    }
}

当然也是可以达到效果,这时候面试官可能就let来延伸es6知识掌握,为什么这里用let就可以达到效果,这里因为let本身有块级作用域,当前的i只在本轮循环中有效。所以每一次循环的i其实都是一个新的变量。 然后可能会再问到js的继承问题,es6又有了class这个类的概念,它又是如何实现继承的: :1st_place_medal: ,然后再考察源生js如何实现继承,又涉及到了原型链以及作用域链等问题. 一步步的进行考察.

Seasons123 commented 6 years ago

大部分人都会做错的经典JS闭包面试题

Seasons123 commented 6 years ago

闭包我所知道的两个作用:

a.通过闭包可以把局部变量传递出来,就是通过闭包可以访问函数内部的变量,比如下面的代码: 1 通过闭包就可以访问函数内部的局部变量,并且实现数量累加。

b.使用闭包可以避免空间污染,闭包内部的变量都只能在内部使用,这样有效避免和外部变量的混淆。(个人理解)