zoukankan      html  css  js  c++  java
  • js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1

    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: 10,
                    b: 20
                };
                
                // 注意词句代码
                Object.prototype.c = 30;
    
                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

  • 相关阅读:
    kali更新源
    中国Linux源镜像站大全
    火狐浏览器Firefox上DownThemAll插件
    使用 backdoor 工具注入ShellCode
    动态加载 ShellCode绕过杀软
    渗透测试的本质与沉思
    Payload 实现分离免杀
    XSS跨站攻击靶场-通关笔记
    Web文件上传靶场
    Python 常用外部模块详解
  • 原文地址:https://www.cnblogs.com/wangfupeng1988/p/3948113.html
Copyright © 2011-2022 走看看