無標題文檔

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 每日测试 - 外一篇

这是期前讨论的,由于比较琐碎,所以整理在一起。

大家认为如下的函数会返回什么?

function test() {
    return
    {
        status: true
    };
}

答案是返回 undefined,因为 return 后面有回车(被认为是条完整的语句),可以认为等效下面的代码

function test() {
    return;
    {
        status: true
    };
}

清羽 同学从 ECMA 上找到了相应的解释

ReturnStatement:
    return [no LineTerminator here] Expressionopt ;    ——from Ecma-262

-- Split --

var Obj = {};
alert(Obj.abc == undefined); //true 

undefined = 'hello, world';
alert(undefined == 'hello, world'); //true

Obj.abc = 'hello, world';
alert(Obj.abc == undefined);

上述的代码最后 alert 的结果为 true 还是 false ?

在 Mozilla 相关的 Javascript 文档中, 对于 undefined 的描述 中可以得知

undefined is a property of the global object, i.e. it is a variable in global scope. 

The initial value of undefined is the primitive value undefined.

所以,「undefined」 的值是可以被覆盖的。所以,上述的答案为 true 。另,相对于「undefined」,null 则为关键字( 来源

null, a special keyword denoting a null value; null is also a primitive value. 
Because JavaScript is case-sensitive, null is not the same as Null, NULL, 
or any other variant

「同样的还有NaN, 可以试一下:」from 小马( 相关解释 )。

var a = parseInt('hello123'); 
alert(a); //NaN

NaN = 'hello123';
alert(NaN == 'hello123'); //true

var b = parseInt('hello123'); 
alert(b == 'hello123');  //?

-- Split --

本期最后一个问题:

<script>
function doClick() {
    alert(1);
}
</script>
<a href="#" onclick="执行:doClick();">测试</a>

上述的代码会执行(弹出 1)吗?详细描述请参看 http://www.hedgerwow.com/360/dhtml/js_label/

-- EOF --

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 圆心。

我的照片

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

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

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

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

分类

搜索

文章