無標題文檔

Javascript 每日测试 - 第九期

今天的题目「看起来」没有任何的悬念。

请问点击第三个链接时弹出的值?

<div id="demo">
    <a href="#">A</a>
    <a href="#">B</a>
    <a href="#">C</a>
    <a href="#">D</a>
</div>

<script type="text/javascript">
var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; ++i) {
        nodes[i].onclick = function(ev) {
            alert(i * 100);
        }
    }
}

addHandlers(document.getElementById('demo').getElementsByTagName('a'));

「很不幸」的是,上述的这段代码没有按照原意实现,点击它们所有的链接都是为 400。这是因为「点击以后执行 i * 100 ,而这个 i 是循环结束以后的值,按照上面的循环后值为 4」。

如果按照期望的写法,也就是点击链接以后 alert 不同的值,可以用闭包。比如下面有几个解决方案

var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; ++i) {
        (function () {
         var j = i * 100;
            nodes[i].onclick = function(ev) {
                alert(j);
            }
        }) ();
    }
}

期前也讨论过 ,只不过那时还没有了解闭包,详细」。类似的题目,在 《精通 Javascript》 中 23 页( 中文版 )有提及。

var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; ++i) {
        nodes[i].onclick = function(idx) {
            return function(ev) {
                alert(idx * 100);
            }
        }(i);
    }
}

「另,如果是使用 YUI 的话,可能会更直观些」

var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; ++i) {
        YAHOO.util.Event.on(nodes[i], 'click', function(ev, idx) {
            alert(idx * 100);
        }, i);
    }
}

使用闭包的话,必须注意两点:其一,就是避免出现无谓的匿名函数;其二,就是注意内存溢出。下面有几条有关闭包的参考链接。

Javascript 每日测试 - 第八期

继续我们今天的 Javascript 每日测试时间,今天的题目是

<ul id="demo">
    <li>a</li>
    <li>b</li>
    <li>c</li>
</ul>

<script type="text/javascript">
var ul = document.getElementById('demo');
var liList = ul.getElementsByTagName('li');

for (var i = 0; i < liList.length; ++i) {
    ul.removeChild(liList[i]);
}
</script>

请问脚本执行的结果是什么?

在 PPK 这本书中提及过 ,getElementsByTagName(tag)返回的 HTML 数组 是会自己动态更新的,并非静态的列表。」 -- from 明城

「更正一下,其实更准确的表述,getElementsByTagName(tag)返回的是 NodeList, 而不是 Array 。」 -- from 小马

如何避免这样的问题?其一,可以换一种循环方式,使用 --i,或者 while 循环,只要代码清晰可读。比如

for(var i = liList.length - 1; i >= 0; i--) {
    ul.removeChild(liList[i]);
}

这样就可以解决上述的问题( 来源 )。

其二,是看情况。比较极端的例子,比如是希望把所有子节点都清除的话,可以直接使用 玉伯 提供的方法

parentNode.innerHTML = '';

有关 innerHTML 效率问题,以目前的电脑硬件而言,排除异常复杂的页面或者逻辑,性能方面应该是非常理想的。

当然,有关 innerHTML 效率方面,还可以改进提高 」 -- from 圆心。

Javascript 每日测试 - 第七期

这期的题目是

请问以下 alert 语句分别弹出的值?

var a = b = c = d = e = f = 1;
alert(a++);
alert(++b); 
alert(++ c);
alert(d ++);
alert(+ +e);
alert(+ + f);

这次主要考验大家对于操作符的理解,特别是一元操作符。让我们先来回顾下 Mozilla 官方 对于操作符方面的解释

下面再理解下 ++ 这个操作符号,通常我们都会将一元操作符直接加在变量的后面。类似的就变成了习惯,以至于对于这样的语句

alert(++                                         b);

就会产生怀疑。但是实际上,他们还是正确的( 来源 )。

「++ c 和 d ++ 只是运算符和运算数之间多了个空格,其实相当于++c和d++,同时建议大家除了 for (var i = 0; i < n; ++i) 这样的应用外,尽量少使用 ++ 和 --, 一来提高代码的可读性,二来避免某些不完善的 code formatter 导致错误」 -- from 小马。

那么上述问题的答案就非常明显了,分别是 1、2、2、1、1、1 。下面,再布置道家庭作业,来自 BT 的 小虎 同志 -_-!

var a = 1;
alert(- + - + + + + - + - - - - - - - + (-+-+-+-+-a++));

请问,上述的 alert 语句会弹出什么值?

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHubTwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 要知道作为码农取名是件很难的事情,所以不想在取名这事情上太费心思。

作为八零后,自认为还仅存点点可能不怎么被理解的幽默感,以及对平淡生活的追求和向往。 为了避免不必要的麻烦,声明本站所输出的内容以及观点仅代表个人,不代表自己所服务公司或组织的任何立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQG91dGxvb2suY29tCg== | base64 -d`

分类

搜索

文章