原生javascript技巧篇

JavaScript编程事项和技巧

首次为变量赋值时务必使用关键字var

如果没有声明直接赋值的话,默认会作为一个新的全局变量,要尽量避免使用全局变量

使用 === 替代 ==

==和!=操作符在有需要的情况下会自动转换数据类型但 === 不会,而且他会同时比较值和数据类型。速度更快

undefined、null、0、false、NaN,空字符串的逻辑结果均为 false

虽然JavaScript语法识别换行,但为了压缩还是在行尾加上分号

使用对象构造器

    function Person(firstName,lastName){
        this.firstName=firstName;
        this.lastName=lastName;
    }
    var Saad=new Person("Saad","Mousliki");

小心使用 typeof、instanceof 和 constructor

  • typeof:JavaScript 一元操作符,用于以字符串的形式返回变量的原始类型,注意,typeof null 也会返回object,大多数的对象数据类型(数组Array、时间Date等) 也会返回 Object
  • contructor:内部原型属性,可以通过代码重写
  • instanceof:JavaScript操作符,会在原型链中的构造器搜索,找到则返回true,否则返回false
    var arr=["a","b","c"];
    typeof arr; //返回 object
    arr instanceof Array; //返回 true
    arr.constructor(); //返回 []

使用自调用函数

函数在创建之后直接自动执行,通常称为自调用匿名函数或直接调用函数表达式。格式如下:

    (function(){
        //置于此处的代码将自动执行
    })();
    (function(a,b){
        var result=a+b;
        return result;
    })(10,20);

从数组中随机获取成员

    function getRandomFormArray(){
        var items=[12,13,14.15,16,17,18,20];
        var randomItem=items[Math.floor(Math.random()*items.length)];
        return randomItem;
    }

获取指定范围内的随机数

    function getRangeRandom(min,max){
        var x=Math.floor(Math.random()*(max-min+1))+min;
        return x;
    }

生成从0到指定值得数字数组

    function getIntegerRangeAarry(max){
        var numbersArray=[];
        for(var i=1;numbersArray.push(i++)<max;);
        return numbersArray;
    }

生成随机的字母数字字符串

    function getGenerateRandomAlphaNum(len){
        var rdmString="";
        for(;rdmString.length<len;rdmString+=Math.random().toString(36).substring(2));
        return rdmString.substr(0,len);
    }

打乱数字数组的顺序

    function upsetArray(){
        var numbers=[5,458,120,-215,228,400,1222505,-48545];
        numbers=numbers.sort(function(){return Math.random()-0.5});
        return numbers;
    }

字符串去空格

    String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"");};

数组追加

    var array1=[12,"f00",{name:"Joe"},-2458];
    var array2=["Doe",555,100];
    Array.prototype.push.apply(array1,array2); 

对象转换为数组

    var argArray=Array.prototype.slice.call(arguments);

验证是否是数字

    function isNumber(n){
        return !isNaN(parseFloat(n)) && isFinite(n);
    }

验证是否是数组

    function isArray(obj){
        return Object.prototype.toString.call(obj)==='[object Array]';
    }//这个 方法有个bug,如果toString()方法被重写过就行不通,可以用下面这个方法:
    Array.isArray(obj);  //its a new Array method

获取数组中的最大值和最小值

    var numbers=[5,458,-215,228,400,1252524];
    var maxInNumbers=Math.max.apply(Math,numbers);
    var minInNumbers=Math.min.apply(Math,numbers);

清空数组

    var myArray=[12,222,1000];
    myArray.length=0;   //myArray will be equal to []

不要直接从数组中delete或 remove元素

解释一下:如果数组中直接使用delete,其实并没有删除元素,而是将元素设置为undefined,数组删除元素用splice。 删除对象属性时可以用delete

    var items=[12,548,'a',2,5478,'foo',8852,'Doe',2154,119];
    items.splice(3,1);   //从元素'a'开始起删除下一个元素。

使用length属性阶段数组

解释一下:length 不仅可以用来清空数组,同样还可以来截断数组:

        var myArray=[1,2,3,4,5,6];  
        myArray.length=5;  //myArray will be equal to [1,2,3,4,5]
        myArray.length=7;  //myArray will be equal to [1,2,3,4,5,undefined,undefined]

逻辑与、或的作用

    var foo=10;
    foo==10 && doSomething();  //等同于 if(foo==10) doSomething();
    foo==5 || doSomething();   //等同于 if(foo!=5) doSomething();
    foo=12 || foo;  //这里用逻辑或 设置优先级或者 默认值,优先级从左到右

使用map() 函数方法对数据循环

    var squares=[1,2,3,4].map(function(val){
        return val*val;
    }); //squares 将变成 [1,4,9,16];

保留指定小数位数

    var num=2.44324545225;
    num=num.toFixed(4);   //num将变成 2.4432

浮点计算的问题

    0.1+0.2====0.3   //false

通过for-in循环检查对象的属性

    for(var name in object){
        //do something with name
    }

逗号操作符

    var a=0;
    var b=(a++,99);  // a变成1  b变成99

临时存储用于计算和查询的变量

在jQuery选择器可以临时存储整个DOM元素

    var aa=$('#aa');

提前检查传入isFinite()的参数

    isFinite(0/0);  //false
    isFiNITE("foo"); //false
    isFinite("10"); //true
    isFinite(10);  //true
    isFinite(undefined); //false
    isFinite();  //false
    isFinite(null) //true,这个特别注意

避免在数组中使用负数做索引

    var numbersArray=[1,2,3,4,5];
    var from=numbersArray.indexOf("foo");  //-1
    numbersArray.splice(from,2); //[5]

用JSON来序列化和反序列化

    var person={name:'Saad',age:26,department:{ID:15,name:'R&D'}};
    var stringFormPerson=JSON.stringify(person); //结果为:{"name":"Saad","age":26,"department":"{"ID":15,"name":"R&D"}}"
    var personFromString=JSON.parse(stringFormPerson);  //personFromString的值与person对象相同

不要使用eval()或者函数构造器

eval()和函数构造器(Function constructor)的开销较大,每次调用,都要将源码转换为可执行的代码。

避免使用with()

使用with()可以把变量加入到全局作用域中,因此,如果存在其他的同名比变量,一来容易混淆,而来值也可能会被覆盖。

不要对数组使用for-in,对象可以

加快循环执行效率的小方法:(减少初始化次数)

    var arrayA=[1,2,3,4,5,6]
    var sum=0;
    for(var i=0,len=arrayA.length;i<len;i++){
        sum+=arrayA[i];
    }

传给setInterval()和setTimeout()时使用函数而不是字符串

解释一下:因为如果传字符串。他们将会进行类似于eval方式的转换,这肯定会要慢点,因此不要使用。正确的写法是传函数名,如下:

    setInterval(doSomethingPeriodically,100);
    setTimeout(doSomethingAfterFiveSeconds,5000);

使用switch/case 代替 一大堆 if/else

当判断有超过两个分支的时候使用switch/case 要更快一些,而且也更优雅,更有利于代码的组织,当然,如果有超过10个分支,就不要使用switch/case 了。

在switch/case中使用数字区间

    function getCategory(age){
        var category="";
        switch(true){
            case isNaN(age):
                category="not an age";
                break;
            case (age>=50):
                category="Old";
                break;
            case (age<=20):
                category="Baby";
                break;
            default:
                category="Young";
                break;
        }
        return category;
    }
    getCategory(5);  //返回 Baby

使用对象作为对象的原形

把给定对象作为参数,来创建以此为原型的新对象:

    function clone(object){
        function oneShotConstructor(){};
        oneShotConstructor.prototype=object;
        return new oneShotConstructor();
    }
    clone(Array).prototype;   //[]

HTML字段转换函数

    function escapeHTML(text){
        var replacements={"<":"<",">":">","&":"&","\":"""};
        return text.replace(/[<>&"]/g,function(character){
            return replacements[character];
        });
    }

不要在循环内部使用try-catch-finally

try-catch-finally中catch部分在执行时将会将异常赋给一个变量,这个变量会被构成一个运行时作用域内的新的变量。

    var object=['foo','bar'],i;
    错误写法:
    for(i=0,len=object.length;i<len;i++){
        try{
            //do something that throws an exception
        }
        catch(e){
            //handle exception
        }
    }
    正确的写法:
    try{
        for(i=0,len=object.length;i<len;i++){
            //do something that throws an exception
        }
    }
    catch(e){
        //handle exception
    }

使用XMLHttpRequests时注意设置超时

XMLHttpRequests时,当长时间执行没有响应,应该中断,可以通过setTimeout()来完成这个工作:

    var xhr=new XMLHttpRequest();
    xhr.onreadystatechange=function(){
        if(this.readyState==4){
            clearTimeout(timeout);
            //do something with response data
        }
    }
    var timeout=setTimeout(function(){
        xhr.abort();//call error callback
    },60*1000);
    xhr.open('GET',url,true);
    xhr.send();

同时需要注意的是,不要同时发起多个XMLHttpRequests请求。

处理WebSocket的超时问题

通常情况下,websocket连接创建后,如果30秒内没有任何活动,服务器端会对连接进行超时处理,防火墙也可以对单位周期没有活动的连接进行超时处理。为了防止这种情况发生,可以每隔一段时间,往服务器端发送一条空的消息。可以用下面两个函数来实现这个需求,一个用于使连接保持活动状态,另一个专门用于结束这个状态。

    var timerID=0;
    function keepAlive(){ //放在WebSocket连接的onOpen()方法的最后面
        var timeout=15000;
        if(webSocket.readyState==webSocket.OPEN){
            webSocket.send('');
        }
        timerId=setTimeout(keepAlive,timeout);
    }
    function cancelKeepAlive(){ //放在onClose()方法的最末尾
        if(timerId){
            cancelTimeout(timerId);
        }
    }

原始操作符比函数调用快

    比如:
    var min=Math.min(a,b);
    A.push(v);
    /*可以代替为:*/
    var min=a<b?a:b;
    A[A.length]=v;

常用的JavaScript检查和压缩工具

  • JSLint
  • JSMin
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值