1. 前言

这两天看了一下TOM大叔的《深入理解js系列》中的基础部分,根据自己的实际情况,做了读书笔记,记录了部分容易绊脚的问题。写篇文章,供大家分享。

2. 关于HTMLCollection的“实时查询”

var divs = document.getElementsByTagName("div"),
i;
for (i = 0; i < divs.length; i++) {
//……
}

以上代码中,会出现性能问题。问题就在于divs是一个HTMLCollection类型的对象,这种类型在每次获取数据时,都会再重新从dom中分析计算。因此,这里的for循环中,每一步循环都会执行一次divs.length的计算,都会令浏览器再重新遍历一遍dom树。
所以,应该在循环之外,早早的计算出divs的length属性值。如下:

var divs = document.getElementsByTagName("div"),
i,
length = divs.length;
for (i = 0; i < length; i++) {
//……
}

3.  for..in...时,注意hasOwnProperty验证

var obj = {
a: ,
b:
}; // 注意词句代码
Object.prototype.c = ; var item;
for (item in obj) {
console.log(item);
}

以上代码中,注意中间标注释的句子。这句代码加与不加,会对下面的for..in..循环产生影响。加上了就输出“c”,不加就不输出“c”。道理很简单,for..in..循环不光能遍历obj对象本身就有的属性,还能遍历obj原型中的属性。

要想屏蔽掉原型中的属性,就用hasOwnProperty函数,如下:

           for (item in obj) {
if (obj.hasOwnProperty(item)) {
//if (Object.prototype.hasOwnProperty.call(obj, item)) {
console.log(item);
}
}

这两句if判断语句,都可以用,效果是一样的。第一个代码可读性好,第二个效率相对较高。建议,没有特殊情况,用第一个即可。

4. 老问题:循环中生成函数/事件的闭包问题

var events = [],
i = 0;
//循环创建函数
for (; i < 10; i++) {
events[i] = function () {
console.log(i);
};
} //验证结果
for (i = 0; i < events.length; i++) {
events[0]();
}

先看以上代码,有js开发经验的人肯定都很熟悉,但是有的人知道,有的人不知道。依照以上代码,循环遍历events数组,执行数组元素中的函数,这10个函数都会打印出什么数字?答案是:全都会输出“10”。下面解释一下原因:

在每个函数生成/被创建时,系统都会给它分配一个变量的环境,这个环境中也包括闭包的数据。但是,当多个环境,公用一个闭包的数据时,是一种引用的关系,这是重点。引用,不是复制。如果改变了这个公用数据,这些公用的环境获取时,也是改变后的数据。

所以,在创建第一个函数时,i === 0,第一个函数引用的闭包中i的值就是0;第二个函数被创建时,i === 1,这是,第一个、第二个两个函数应用闭包中i的值,都是1。以此类推,直到第十个函数创建时,i === 9;但是在for循环的最后一步,又执行了 i++;所以i === 10。

明白了吗?

想要改变这个问题,想要每个函数都输出不同的数值,那就需要不让每个函数都公用一个闭包——让每个函数使用单独的闭包数据,不共享。只需讲for循环创建函数的部分修改为:

//循环创建函数
for (; i < 10; i++) {
events[i] = (function (index) {
return function (index) {
console.log(index);
}
})(i);
}

此时,i作为参数,传入匿名自动执行函数,赋值给index参数。这个匿名函数的变量环境,就把index保存了下来,而不会随着i的变化而变化。这就是要点。

欢迎关注微博:weibo.com/madai01

js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1的更多相关文章

  1. js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

    1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭 ...

  2. javascript - 浏览TOM大叔博客的学习笔记

    part1 ---------------------------------------------------------------------------------------------- ...

  3. hexo博客的学习笔记

    这篇文章主要的作用是作为 .md文件打开,内部的格式为一个初学者对hexo以及markdown语法运用的笔记 1.Hexo的写文格式 最开始为文章的属性部分,以三横杠-开始,-结束.里面记录了文章的标 ...

  4. Git--廖雪峰的博客的学习笔记

    为了督促自己能看完这个网站的学习教程,边看边做了些简要的笔记,记录了常用命令,其实也就是自己打了些简单的命令,好多直接就粘贴过来了,也算是一个学习的证明吧,想按详细的教程,还是要去博主的园子学习啊地址 ...

  5. 我的第一篇博客----LCS学习笔记

    LCS引论 在这篇博文中,博主要给大家讲一个算法----最长公共子序列(LCS)算法.我最初接触这个算法是在高中学信息学竞赛的时候.那时候花了好长时间理解这个算法.老师经常说,这种算法是母算法,即从这 ...

  6. js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)

    1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...

  7. ibatis 学习笔记 3 - pfpfpfpfpf的专栏 - 博客频道 - CSDN.NET

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  8. OpenGL ES 学习笔记 - Overview - 小旋的博客

    移动端图形标准中,目前 OpenGL ES 仍然是比较通用的标准(Vulkan 则是新一代),这里新开一个系列用于记录学习 OpenGL ES 的历程,以便查阅理解. OverView OpenGL ...

  9. 11.3 Go 开发博客

    11.2 Go 开发博客 1.1. MVC模式 MVC分层简化了分组开发.不同的开发人员可同时开发视图,控制器逻辑和业务逻辑. 耦合性低:视图层和业务逻辑层分离.相互独立,不受影响 重用性高:业务逻辑 ...

随机推荐

  1. linux上搭建redis

    环境centos7及redis-4.0.2.tar.gz 第一步首先在/usr/local/mypackage下mkdir redis 通过工具上传redis安装包 解压安装包 tar -zxvf r ...

  2. 20169207《Linux内核原理与分析》第八周作业

    本章的作业依旧包括两部分,1.阅读学习教材「Linux内核设计与实现 (Linux Kernel Development)」第教材第11,12章. 2.学习MOOC「Linux内核分析」第六讲「进程的 ...

  3. noip第21课作业

    1. 遍历二叉树 [问题描述] 以先序的方式建立一棵二叉树,空结点用‘#’号表示,例如:abd###ce##f##,将建立一棵如下的二叉树: 输出其中序序列和后序序列,其中总结点个数不超过100. 输 ...

  4. Android 响应menu,back键,点击外部消失

    点击外部消失,只需要设置popupWindow.setBackgroundDrawable(new PaintDrawable()); 设置 popupWindow.setFocusable(true ...

  5. POJ3666 线性dp_离散化_贪心

    POJ3666 线性dp_离散化_贪心 就DP而言这个题不算难,但是难就难在贪心,还有离散化的思想上 题目大意:n个土堆,问你最少移动多少单位的图,可以使得这n个土堆变成单调的 dp[i][j]表示前 ...

  6. 防Xss注入

    转自博客:https://blog.csdn.net/qq_21956483/article/details/54377947 1.什么是XSS攻击 XSS又称为CSS(Cross SiteScrip ...

  7. js五道经典练习题--第四道qq好友列表

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  8. Brain Rules: 12 Principles for Surviving and Thriving at Work, Home, and School

    选自 https://litemind.com/brain-rules/

  9. lnmp mysql添加用户命令

    cd /usr/local/mysql/bin/grant all privileges on *.* to 'root'@'%' identified by '12345678';flush pri ...

  10. 扩展 StackExchange.Redis 支持实体

    一.StackExchange.Redis StackExchange.Redis是由Stack Overflow开发的C#语言Redis客户端,使用广泛,本文针对 StackExchange.Red ...