美文网首页JavaScript
JavaScript 高级用法

JavaScript 高级用法

作者: _leizi | 来源:发表于2018-01-03 16:46 被阅读0次

    内容来自:《JavaScript高级程序设计》、MDN

    1、防止篡改对象
    限制对象扩展:Object.preventExtensions(obj);

    Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。

    var person = {age:1};
    Object.preventExtensions(person);
    person.name = 'mike';
    console.log(person.name);//undefined
    console.log(Object.isExtensible(person));//false
    

    使用Object.istExtensible()方法还可以确定对象是否可以扩展。

    密封对象:Object.seal(obj);

    Object.seal() 方法可以让一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性,并且会将所有已有属性的可配置性(configurable)置为不可配置(false),即不可修改属性的描述或删除属性。但是可写性描述(writable)为可写(true)的属性的值仍然可以被修改。

    使用Object.isSealed()方法可以确定对象是否被密封了。因为被密封的对象不可扩展,所以用Object.isExtensible()检测密封的对象也会返回false。

    var person = {age:1};
    Object.seal(person);
    person.name = 'mike';
    console.log(person.name);//undefined
    console.log(Object.isExtensible(person));//false
    console.log(Object.isSealed(person));//true
    
    冻结对象:Object.seal(obj);

    Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。冻结的对象既不可扩展,又是密封的。

    Object.isFrozen()方法用于检测冻结对象。因为冻结对象既是密封的又是不可扩展的,所以用Object.isExtensible()和Object.isSealed()检测冻结对象将分别返回false和true。

    var person = {age:1};
    Object. freeze(person);
    person.age = 2;
    console.log(person.age);//undefined
    console.log(Object.isExtensible(person));//false
    console.log(Object.isSealed(person));//true
    console.log(Object. isFrozen(person));//true
    
    2、定时器
    重复定时器

    下面代码中是链式调用setTimeout(),每次函数执行的时候都会创建一个新的定时器。第二个setTimeout()调用使用了arguments.callee来获取对当前执行的函数的引用,并为其设置另外一个定时器。这样做的好处是,在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔。而且,它可以保证在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行。这个模式主要用于重复定时器,如下例所示。

    注:arguments.callee 属性包含当前正在执行的函数。callee 是 arguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数。这在函数的名称是未知时很有用,例如在没有名称的函数表达式 (也称为“匿名函数”)内。

    setTimeout(function(){
       //处理代码
       setTimeout(arguments.callee, timer);
    },timer)
    
    使用重复定时器代替循环

    起因:现代浏览器为JavaScript运行都被分配了一个确定数量的资源,这样做的目的是:防止恶意的代码把用户的计算机搞挂了。其中一个限制是长时间运行脚本的制约,如果代码运行超过特定的时间或者特定语句数量就不让它继续执行。如果代码达到了这个限制,会弹出一个浏览器错误的对话框,告诉用户某个脚本会用过长的时间执行,询问是允许其继续执行还是停止它。所有JavaScript开发人员的目标就是,确保用户永远不会在浏览器中看到这个令人费解的对话框。定时器是绕开此限制的方法之一。

    脚本长时间运行的问题通常是由两个原因之一造成的:过长的、过深嵌套的函数调用或者是进行大量处理的循环。这两者中,后者是较为容易解决的问题。长时间运行的循环通常遵循以下模式:

    for(var i=0; i < data.length; i++){
        code(data[i]);//处理代码
    }
    

    这种循环模式的问题在于要处理的项目的数量在运行前是不可知的。如果完成code()要花100ms,只有2个项目的数组可能不会造成影响,但是10个的数组可能会导致脚本要运行一秒钟才能完成。数组中的项目数量直接关系到执行完该循环的时间长度。同时由于JavaScript的执行是一个阻塞操作,脚本运行所花时间越久,用户无法与页面交互的时间也越久。

    在解决这个问题之前,开发者需要确定一个代码逻辑:如果没有for循环的阻塞,会出现其他的逻辑混乱,那么最好不要改动它。若不会影响其他代码或页面效果,可以使用以下方法。

    setTimeout(function(){
       var item = data.shift();
       code(item);
       if(data.length>0{
            setTimeout(arguments.callee, timer);
       }
    },timer)
    

    上述的代码含义是:使用定时器分割for循环。这是一种叫做数组分块(array chunking)的技术,小块小块地处理数组,通常每次一小块。基本的思路是为要处理的项目创建一个队列,然后使用定时器取出下一个要处理的项目进行处理,接着再设置另一个定时器。

    函数节流
    var n=0;        
    window.onresize = function(){
        console.log(++n);
    }
    

    浏览器中某些计算和处理要比其他的昂贵很多。例如,DOM操作比起非DOM交互需要更多的内存和CPU时间。连续尝试进行过多的DOM相关操作可能会导致浏览器挂起,有时候甚至会崩溃。尤其在IE中使用onresize事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发。在onresize事件处理程序内部如果尝试进行DOM操作,其高频率的更改可能会让浏览器崩溃。为了绕开这个问题,你可以使用定时器对该函数进行节流。

    函数节流背后的基本思想是指,某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。以下是该模式的基本形式:

    var n=0;  
    function resizeHandler() {  
        console.log(n);  
        n++;  
    }  
    function throttle(method, context) {  
        clearTimeout(method.tId);  
        method.tId=setTimeout(function(){  
            method.call(context);  
        },500);  
    }  
    window.onresize = function(){  
        throttle(resizeHandler);
    };
    

    多数情况下,用户是感觉不到变化的,虽然给浏览器节省的计算可能会非常大。 只要代码是周期性执行的,都应该使用节流,但是你不能控制请求执行的速率。这里展示的throttle()函数用了100ms作为间隔,你当然可以根据你的需要来修改它。

    3、其他

    赋值

    var i=1,ret;
    ret=i!==1||true;
    console.log(ret); //true

    相关文章

      网友评论

        本文标题:JavaScript 高级用法

        本文链接:https://www.haomeiwen.com/subject/sktknxtx.html