• JS深入学习知识整理



    属性与原型
    function foo(){this.add = function(){};}
    ②foo.prototype.add = function(){};
    ①中的add是属性;②中的add是原型。
    当调用foo.add时,查询顺序:foo属性--->foo原型--->Object原型
    foo.prototype.hasOwnProperty(prop);判断prop是否为foo的自身属性。
    delete只能删除属性(除了window对象的属性和 configurable=false 的属性),不能删除原型
     

    原型链和构造函数
    function Foo(name){
      this.name=name;
    }
    Foo.prototype.run=function(){};
    var f = new Foo("Test");
    
    注:IE中不支持__proto__。
    f.__proto__===Foo.prototype //true
    f.__proto__.run === Foo.prototype.run //true
    f.run ===f.__proto__.run //true
    f.constructor ===Foo //true
    Foo.prototype.constructor === Foo //true 

    继承方式中易犯的错误:

    Son.prototype = Father.prototype
    
    这时如果修改Son的原型链,Father的原型也会被修改
    
    原因:Son继承的是Father的原型链地址,所以修改的也是该地址的内容。

    闭包

    简单的定义:有权访问另一个函数作用域中的变量的函数。
    从理论角度:所有的函数。因为任意函数在创建之初就已将外层上下文保存起来了。 哪怕是简单的全局变量也是如此,因为函数中访问全局变量就相当于是在访问自由变量,这个时候使用最外层的作用域。 从实践角度:以下函数才算是闭包: 即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回)在代码中引用了自由变量

    闭包很强大,但是不合理的应用也是会付出代价的,因为创建闭包必须维护额外的作用域,这可能会占用大量内存。

    因为IE8以下版本垃圾回收机制的问题,如果闭包的作用域链中保存着DOM元素,则该元素无法被回收。即传说中的内存泄露

    可参照IE内存泄露分析 。Demo:

    var but = document.getElementById("button1");
    var text = document.getElementById("textbox1");
    but.onclick = function() {
        /*现在是在闭包中*/
        alert(text.value);
    };

    对应方法:

    var but = document.getElementById("button1");
    var text = document.getElementById("textbox1");
    var textValue = text.value;
    but.onclick = function() {
        /*现在是在闭包中*/
        alert(textValue);
    };
    即 把闭包中的DOM元素通过其他方式去除。不过这在工作中,显然不太容易。。。

    执行上下文

    JS中仅有函数能创建新的作用域。if,while,for...则不能。如下
    for(var i=0;i<2;i++){}
    alert(i);
    此时不会出现 ReferenceError 。
    
    数组元素的this指向该数组对象,例如
    var arr = [function(){return this;},3,"SS"];
    则 arr[0]()===arr;

    typeof 与 instanceof

    typeof 只能用来判断变量属于哪一种基本类型,即string,boolen,function等等
    
    instanceof 用于判断对象的从属关系
    例如 var foo = new Foo();
    则 foo instanceof Foo===true
    在ES5中可以用getPrototypeOf或isPrototypeOf来完成相同功能
    例如 Object.getPrototypeOf(foo) === Foo
    Foo.prototype.isPrototypeOf(foo)

    arguments:对象当前所执行的函数;不是数组,但访问方式与数组相同;可用于模拟方法重载。

    属性:
    length 当前方法的传过来的参数个数;
    callee  当前正在执行的Function对象,且仅当改函数正在执行时才可用,常用于递归运算(同样适用于匿名函数)
    例如 function foo(a,b,c){...}  foo(1,3);
    arguments.callee===foo //true
    arguments.length ===2 //true
    foo.length === 3 //true 且只读(即使赋值foo.length=10,输出的时候foo.length仍然为3)
    arguments.length与foo.length的区别在于,前者是实参个数,后者是形参个数

    组件模式(紧耦合增益):

    var Module = (function(obj){
        obj.old_Method = obj.Method;
        obj.Method = function(){...};
        return obj;
    }(Module ||  {}));

     函数表达式

    函数声明与函数表达式的区别:

    ①通过函数声明定义的函数在进入上下文阶段就已经创建;如

    function A(){
        ....
    }

    ②而函数表达式则先定义一个变量,当代码执行时才将匿名函数赋给该变量。如

    var B = function(){
        ....
    }

    二者还有个区别就是二者的name属性不同。函数声明的name是方法名,而函数表达式的name则为空字符串.


    对构造函数和一般的函数来说,搞清this所指向的对象并不困难。但匿名函数就比较头晕了。就向下面的这段东东

    function A(){
        console.log(this);
        eval('console.log(this)');
        (function(){
            console.log(this);
            eval('console.log(this)');
        })()
    }
    new A()

    匿名函数的执行环境具有全局性,因此其中的this对象通常指向window


    获取对象属性名

    Object.keys(obj)//感觉这个方法不错,不仅仅是JS对象,连DOM对象的属性名也可以获取


     使用JavaScript修改DOM树(考虑性能)

    浏览器下载完页面中的所有组件之后会解析生成DOM树、渲染树两个数据结构,然后开始绘制页面元素;
    当DOM的变化影响了元素的几何属性,会导致浏览器重新构造渲染树,这个过程叫做重排。
    重排之后浏览器会重新绘制受影响的部分到屏幕,这个过程叫做重绘。
    而重排和重绘都是代价昂贵的操作,会使web应用程序的UI反应迟钝。
    所以在需要对DOM元素进行一系列操作时,要将重绘和重排最小化:
    (1)使元素脱离文档流;
    (2)对其应用多重改变;
    (3)将元素带回文档中;
    有三种方法可以使DOM脱离文档:

    //1:隐藏元素,应用修改,重新显示;如
    var div = document.getElementById("xx");
    div.style.display = "none";
    //TODO
    div.style.display = "";
    
    //2:使用文档片段,在当前DOM之外构建一个子树,再把它拷贝回文档;如
    var cdf = document.createDocumentFragment();
    var child;
    for(var i = 0;i<100;i++){
        child = document.createElement("div");
        cdf.appendChild(child);
    }
    document.body.appendChild(cdf);
    //3:将原始元素拷贝到一个脱离文档的节点中,修改副本,完成后再替换原始元素;

     

  • 相关阅读:
    Python 数据分析中金融数据的来源库和简单操作
    Python 数据分析中常用的可视化工具
    Pandas 时间序列处理
    Ubuntu 下使用 python3 制作读取 QR 码
    Ubuntu中找不到pip3命令的解决方法
    Ubuntu 中查找软件安装的位置
    将文件进行分类整理
    树的遍历
    Junit4知识梳理
    springboot中controller的使用
  • 原文地址:https://www.cnblogs.com/TiestoRay/p/2681009.html
Copyright © 2020-2023  润新知