经验总结之javascript篇

新地址:https://github.com/hezizi/Blog/issues/4,欢迎戳

此篇文章主旨是记录js中常见,易犯错,重要等相关知识点(不定期更新)


window.onload和$(document).ready()的区别

    window.onload是在页面中包含图片在内的素有元素全部加载完成再执行;

    $(document).ready()是DOM文档树加载完成之后执行,不包含图片,其他媒体文件;

    因此$(document).ready()快于window.onload执行

数组去重

const arr = ['a','bb','22','a','yuci','haha','22'];

    1. es6的Set数据结构

        let unique = new Set(arr);
        console.log(Array.from(unique));

    2. 使用push()

        let arr2 = [];
        for(let i = 0; i < arr.length; i++) {
            if(arr2.indexOf(arr[i]) == -1) { //不包含某个值则返回-1
                arr2.push(arr[i]);
            }
        }
        console.log(arr2);
        //如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组
        let arr3 = [arr[0]];
        for(let i = 1; i < arr.length; i++) {
            if(arr.indexOf(arr[i]) == i) {
                arr3.push(arr[i]);
            }
        }
        console.log(arr3);

    3. 排序去除相邻重复元素

        let arrSort = arr.sort();
        let arr4 = [];
        for(let i = 0; i< arrSort.length; i++) {
            if(arrSort[i] != arrSort[i+1]) {
                arr4.push(arrSort[i]);
            }
        }
        console.log(arr4);

    4. 使用splice()

        let len = arr.length;
        for(let i = 0; i < len; i++) {
            for(let j = i + 1; j < len; j++) {
                if(arr[i] === arr[j]) {
                    arr.splice(i,1);
                    len--;
                    j--;
                }
            }
        }
        console.log(arr);

事件委托

    得益于事件冒泡,当多个元素有相同的事件,将事件绑定在父元素

        var oUl = document.getElementById('oul');
	oUl.addEventListener('click', function(e) {
	    var e = e||window.event;
	    var tar = e.target;
	    if(tar.nodeName === 'LI') {
	        alert(tar.innerHTML);
	    }
	})

    更详细请看:事件委托

判断变量类型

    typeof()用于判断简单数据;

    判断一个变量是对象还是数组使用instanceof,constructor或Object.prototype.toString.call();

    更详细请看:判断数据类型

同步和异步

    同步:由于js单线程,同步任务都在主线程排队执行,前面任务没执行完,后面任务一直等待;

    异步:不进入主线程,进入任务队列,等待主线程任务执行完成,开始执行。最基础的异步操作setTimeout和setInterval,主线程任务执行完成,开始执行里面的函数

返回false的几种情况

    false,null,0,“”,undefined,NaN

js类型值的区别

    存储地:

    简单数据类型:存储在栈中;

    引用数据类型:存储在堆中,在栈中存储了指针,指向存储在堆中的地址,解释器会先检索在栈中的地址,从堆中获得实体;

    大小:

    简单数据类型:大小固定,占用空间小,频繁使用,所以存储在栈中;

    引用数据类型:大小不固定,占用空间大;

闭包

    何为闭包:有权访问另一个作用域中变量的函数

    闭包特性:可实现函数外访问函数内变量,外层变量可以不被垃圾回收机制回收

    为什么?怎么解决?

        for(var i = 0; i < 10; i++) {
            setTimeout(function() {
                console.log(i);  
            }, 1000);
        }

    输出结果都为10,因为for()循环过程中每次传值,匿名函数并没有执行,相当于执行10次function(){console.log(i);},循环结束i变为10,所以输出全部为10;

    使用闭包,自执行匿名函数包裹

        for(var i = 0; i < 10; i++) {
            (function(j) {
                setTimeout(function() {
                    console.log(j);  
                }, 1000);
            })(i);
        }

    外部匿名函数立即执行,把 i 作为参数,赋值给 j ,因为是立即执行,所以每次循环输出不同值。

    引用外层变量不被回收,会相比其他函数占用更高内存,使用不当容易造成内存泄漏。

this的指向

    全局范围:指向window(严格模式下不存在全局变量,指向undefined);

    普通函数调用:指向window;

    对象方法调用:指向最后调用它的对象;

    构造函数调用:指向new出来的对象;

    显示设置this:call,apply方法显示将this指向第一个参数指明的对象;

new具体做了些什么

    创建一个新对象foo;

    并将它的__proto__指向其构造函数的prototype,foo.__proto__ = Foo.prototype;

    动态将this指向新对象,Foo.apply(foo,arguments);

    执行函数体中的代码;

    放回新对象foo;

原型和原型链

    创建一个函数就会为其创建一个prototype属性,指向这个函数的原型对象,原型对象会自动获得constructor属性,指向prototype属性所在函数。

        Function.prototype.a = "a";  
        Object.prototype.b = "b";  
        function Person(){}  
        console.log(Person);    //function Person()  
        let p = new Person();  
        console.log(p);         //Person {} 对象  
        console.log(p.a);       //undefined  
        console.log(p.b);       //b  

    p.__proto__ === Person.prototype;Person.prototype.constructor === Person

    当调用某种方法或查找某种属性时,首先会在自身调用和查找,如果自身并没有该属性或方法,则会去它的__proto__属性中调用查找,也就是它构造函数的prototype中调用查找,如果构造函数中也没有该属性方法,则会去构造函数的隐式原型中查找,一直到null,就这样形成原型链。

    更多请看:原型和原型链

继承方式

    原型链继承:

    Child()的原型作为Parent()的实例来继承Parent()的方法属性

    因为所有实例都继承原型方法属性,其中一个实例对原型属性值更改后,所有实例调用该属性的值全部更改

        function Parent() {}
        Parent.prototype.parentSay = function() {
            return 'i am parent';
        }
        function Child() {}
        Child.prototype.childSay = function() {
            return 'i am child';
        }
        Child.prototype = new Parent();
        var par = new Parent();
        var kid = new Child();

        console.log(kid.parentSay());           //i am parent

    构造函数继承:

    在子类的构造函数内部通过call或apply来调用父类构造函数

    无法实现函数的复用

        function People() {
            this.name = ['zhangsan','lisi','wangwu'];
        }
        function Person() {
            People.call(this);
        }
        var per1 = new Person();
        per1.name.push('zhanliu');
        console.log(per1.name);     //["zhangsan", "lisi", "wangwu", "zhanliu"]

        var per2 = new Person();
        console.log(per2.name);     //["zhangsan", "lisi", "wangwu"]

    组合继承:

    将原型链继承和构造函数继承结合,最常用的继承模式

    原型链继承共享的属性和方法,构造函数继承实例属性

        function People(num) {
            this.num = num;
            this.name = ['zhangsan','lisi','wangwu'];
        }
        People.prototype.numCount = function() {
            console.log(this.num);
        }
        function Person(num) {
            People.call(this, num);
        }
        //继承方式
        Person.prototype = new People();
        Person.prototype.constructor = Person;
        
        var per1 = new Person(10);
        per1.name.push('zhaoliu');
        console.log(per1.name);     //["zhangsan", "lisi", "wangwu", "zhanliu"]
        per1.numCount();            //10

        var per2 = new Person(20);
        console.log(per2.name);     //["zhangsan", "lisi", "wangwu"]
        per2.numCount();            //20

    更多继承方式请看:继承方式

数组常用方法

    改变原数组:

    尾部删除pop(),尾部添加push(),头部删除shift(),头部添加unshift(),排序sort(),颠倒数组元素reverse(),删除或插入元素splice();

    不会改变元素组:

    合并数组concat(),拼接数组元素join(),截取元素slice(),indexOf(),lastIndexOf(),toString()

    更多方法总结请看:Array数组方法总结

数据存储

    Cookie:用于客户端与服务端通信,也具有本地存储的功能

    localStorage,sessionStorage:专门用于存储

    区别:

    大小:Cookie容量为4K,因为用于客户端与服务端通信,所有http都携带,如果太大会降低效率; localStorage,sessionStorage大小为5M。

    失效时间:Cookie会在浏览器关闭时删除,除非主动设置删除时间;localStorage一直都在直到用户主动删除或清除浏览器缓存;sessionStorage在浏览器关闭时删除。


结束语

    这篇文章主要是总结js中常见知识点,会不断更新,因为是总结,所以并没有特别深入,个人总结如有错误欢迎指正。想了解更多js深入的可以查看  深入javascript系列  。

猜你喜欢

转载自blog.csdn.net/yucihent/article/details/79878255
今日推荐