网页前端设计

http://www.86y.org

搜索文章

js操作dom类总结

用声音读出全文关注我吧
 2012/10/10 16:17:29 阅读次数:16240

今天发现原来对JS的自定义属性使用相见如初。学习了下,解决了一些问题,所以把这些都记录下来,说不定下次还用的着。

 

基础知识

JS的6种类型
数字类型、字符串类型、布尔类型、函数类型、对象类型、未定义类型。

||会把它两边为真的返回去。如果两边都为假则返回后面的,如 false || 0,返回0。

DOM操作

childNodes在标准浏览器下会获取空白节点 ( 火狐 )。如代码中不可见的换行符,在所有浏览器下注释也被算做一个节点。
children没有兼容问题


document.createElement('tag')        创建标签
obj.appendChild(node)            将node添加到obj内 ( 创建子节点 )
obj.insertBefore(newNode, node)        在obj里将newNode插入到node前
obj.removeChild(node)            在obj里移除node节点

obj.setAttribute('_url', 'http://www.yongche100.com')        设置自定义属性
obj.getAttribute('_url')                    获取自定义属性
obj.removeAttribute('value')                    删除自定义属性,IE下有问题。

node.cloneNode(true)            克隆节点,true克隆节点内的内容,false仅克隆标签,不克隆里面的内容。


封装查找节点

function first(obj)
{
    return obj.firstElementChild || obj.firstChild;
}

function last(obj)
{
    return obj.lastElementChild || obj.lastChild;
}

function next(obj)
{
    return obj.nextElementSibling || obj.nextSibling;
}

function pre(obj)
{
    return obj.previousElementSibling || obj.previousSibling;
}

字符串操作

字符串方法
str.charAt(i)        获取第i位字符
charCodeAt()        将字符编码( ASCII码 ),str.charAt(i).charCodeAt();
fromCharCode()        将ASCII码解码固定写法,String.fromCharCode(22825);
indexOf(字符, 起始位置)    搜索某个字符在字符串里出现的位置,第二个参数的作用是从哪里开始搜索( 不写则从起始位置开始 )。str.indexOf('B', 2);
subString(起始, 结束)    截取字符串,str.subString(1, 5),截取str字符串从第1位字符至第5位字符之间的内容( 不包括结束位 ),结束位置不写则截取至字符串末尾。
subStr(起始, 长度)    截取字符串,str.subStr(2, 5),截取str字符串从第2位开始截取5位。
str.toUpperCase()    将字符串转为大写
str.toLowerCase()    将字符串转为小写

str.splice(起始位置,替换长度,替换内容)    替换、添加、删除字符。
1. 添加    替换长度为0时添加字符。
2. 删除 没有替换内容是则删除。

数组操作

数组方法
join('分隔符');        按照分隔符将数组转化成字符串
split('分隔符');    按照分隔符将字符串转化成数组
pop();            从数组尾部弹出元素,返回弹出的元素
shift();        从数组头部弹出元素,返回弹出的元素
push(元素);        从数组尾部插入元素,返回插入元素后的数组长度
unshift(元素);        从数组头部插入元素,返回插入元素后的数组长度
arr1.concat(arr2)    连接两个数组
arr.sort(fn)        数组排序,arr.sort(function (num1, num2) { return num1 - num2; } );    返回正数不交换位置( 正序 ),返回负数则交换位置  ( 倒序 )。
arr.reverse()        反转数组,将数组内容反转。

arguments        不定参数时,类似参数数组。
例:
function pop()
{
    alert(argument.length);
}

pop(1, 2, 3, 4, 5);


BOM操作

offsetWidth实际的宽度 ( width + padding + border )
clientWidth内部的宽度 ( width + padding )

window.close标准下不支持 ( 火狐 )

window.location.href     整个网址
window.location.search    获取?后面的内容,包括? 不会获得#后的内容
window.location.hash    获取#后面的内容,包括#

obj.clientHeight    对象可视高度
obj.scrollHeight    对象实际高度
obj.scrollTop        对象滚动条滚动距离


滚动距离
document.documentElement.scrollTop    标准
document.body.scrollTop            IE


获取选中文字

function text()
{
    if(document.selection)
    {
        return document.selection.createRange().text;
    }
    else
    {
        return window.getSelection().toString();
    }
}

事件

事件流分为
1. 冒泡阶段
结构嵌套关系下,子级元素事件会触发父级元素相同事件,此时如需阻止冒泡用cancelBubble。
阻止冒泡
ev.cancelBubble = true;

2. 捕获阶段
IE:        没有捕获阶段
标准 ( 火狐 ):    只有在绑定事件中才能看见捕获阶段

全局捕获
事件在窗口可视区范围内有效
设置全局捕获obj.setCapture(),释放全局捕获obj.releaseCapture();


普通事件与绑定事件
普通事件:用一个元素,加同一个事件,执行不同的效果,后面的会把前面的覆盖掉。
绑定事件:都会执行,不会互相覆盖。

绑定事件
ie和标准下绑定的区别:
1.参数不同
2.加不加on
3.执行顺序
4.this指向不一样

IE:        attachEvent() :    第一个参数:什么事件,        第二个参数:执行的函数(倒序执行)
                    obj.attachEvent('on' + event, fn)
标准 ( 火狐 ):    addEventListener() :    第一个参数:什么事件(不加on),    第二个参数:执行的函数,    第三个参数:一个布尔值:false(冒泡) true(捕获)
                    obj.addEventListener(event, fn, false)

封装绑定事件函数

bindEvent(obj, ev, fn)
{
    if(obj.addEventListener)
    {
        obj.addEventListener(ev, fn, false);
    }
    else
    {
        obj.attachEvent('on' + ev, function () {
            fn.call(obj);
        });
    }
}

取消事件

普通事件:    object.onclick = null;
绑定事件:
       IE     obj.detachEvent('on' + event, fn);
标准 ( 火狐 )  obj.removeEventListener(event, fn, false);

封装取消事件函数
delEvent(obj, ev, fn)
{
    if(obj.removeEventListener)
    {
        obj.removeEventListener(ev, fn, false);
    }
    else
    {
        obj.detachEvent('on' + ev, fn);
    }
}

键盘事件

获取键值:ev.keyCode
Ctrl键:  ev.ctrlKey

鼠标事件

右键事件:obj.oncontextmenu = function () {};
鼠标样式替换:cursor:url(ico.cur), auto; ( auto浏览器根据当前情况自动确定鼠标光标类型 )

鼠标滚轮事件

IE/Chrome :onmousewheel
Firefox :   DOMMouseScroll :以DOM事件开始的叫做DOM事件(绑定事件才能执行

绑定鼠标滚轮事件

if(obj.addEventListener)
{
    obj.addEventListener('DOMMouseScroll', fn, false);
}

obj.onmousewheel = fn;

判断滚轮滚动方向
var bBtn = true;
if(ev.detail)
{
    bBtn = ev.detail>0 ? true :false;
}
else
{
    bBtn = ev.wheelDelta<0 ? true :false;
}

bBtn = true  向下滚
bBtn = false 向上滚
      
阻止默认事件

普通方式:return false;
绑定方式:event对象下:preventDefault();

if(ev.preventDefault)
{
    ev.preventDefault();
}
else
{
    return false;
}

call改变this指针

fn.call(obj, pram)

第一个参数obj为运行环境
第二个参数起为真正的参数


Cookie操作

Cookie

存:document.cookie :格式:key=value

cookie :一个网站最多存储20几个cookie
cookie :本地环境必须在火狐浏览器下,其他浏览器在服务器环境下无效
cookie :中的等号不是赋值,而是添加
cookie :是临时性存储的,关闭浏览器就会消失,不想消失就要设置过期时间


cookie :存中文的时候要编码:encodeURI 取要解码 decode


封装Cookie

function setCookie(key, value, times)
{
    var oDate = new Date();
    oDate.setDate(oDate.getDate() + times);
    document.cookie = key + '=' + encodeURI(value) + ';expires=' + oDate;
}

function getCookie(key)
{
    var a = document.cookie.split('; ');
    for(var i=0; i<a.length; i++)
    {
        var b = a[i].split('=');
        if(b[0] == key)
        {
            return decodeURI(b[1]);
        }
    }
}

function delCookie(key)
{
    setCookie(key, 1, -1);
}


AJAX操作

AJAX

异步与同步的区别    异步:同一时间做多件事情    同步:同一时间做一件事情

AJAX交互方式:1.即发送数据又接收数据  2.只发送数据,不接收数据 3.只接收数据,不发送数据

AJAX必须要统一编码

HTTP状态码    1xx 消息    2xx 成功    3xx 重定向    4xx 请求错误    5xx 服务器错误

AJAX工作流程
1. 初始化Ajax对象
2. 建立连接
3. 监控请求状态
4. 发送请求

创建AJAX对象
AJAX对象
微软:    ActiveXObject("Microsoft.XMLHTTP");
标准:    XMLHTTPRequest();

建立连接

oAjax.open(方式,请求地址, 是否异步通信)

方式分为GET和POST方式,一般用GET方式( IE支持的最大URL长度是2KB,URL会被缓存,容易被别人获取 ),需要发送大量数据时用POST方式( 较安全 )。
是否异步通信一般为true。

GET与POST的区别

1.传输的方式不一样:GET:数据在网址问号的后面 POST:看不见的一个传输体中,被发送上去的
2.GET是不安全的,POST相对安全的
3.IE下网址过长会被自动截断,get :2048~2083字节 POST:理论是没有上限的
4.get:页面会被缓存,POST:页面不会被缓存

示例:oAjax.open('get', url, true);

监听请求状态

readyState的5种状态
0 - ( 未初始化 )    还没有调用send()方法
1 - ( 载入 )        已调用send()方法,正在发送请求
2 - ( 载入完成 )    send()方法执行完成,已经接收到全部响应内容
3 - ( 交互 )        正在解析响应内容
4 - ( 完成 )        响应内容解析完成,可以在客户端调用了

发送请求

GET  :oAjax.send();
POST :oAjax.setRequestHeader('content-type', 'urlencode');
       oAjax.send(sData);    //sDate为需要发送的数据
 

Eval

eval    将字符串转成JS语句,字符串两边是大括号{}( 例如JSON数据 )会有问题,需加在两边'(' + 字符串 + ')'。

示例:

将AJAX请求回来的JSON格式的字符串转成JSON对象
eval('(' + {name:'Baie', age:23} + ')');

将函数格式语句转换成可执行的JS函数
eval('function test() { alert("Hellow World"); } test();');


AJAX封装 ( ajax.js )

function ajax(sUrl, fnOnScuss, fnOnFail)
{
    //1.创建ajax对象

    var oAjax = null;
    
    if(window.ActiveXObject)
    {
        oAjax = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {
        oAjax = new XMLHttpRequest();
    }
    
    //2.连接服务器 :第一个参数:请求的方式 第二个参数:请求的地址 第三个参数:是不是异步的
    
    oAjax.open('GET', sUrl, true);
    
    //3.监听服务器 : responseText(数据库返回的数据)
    
    oAjax.onreadystatechange = function()
    {
        if(oAjax.readyState == 4)
        {
        
            if(oAjax.status == 200)        //OK
            {
                fnOnScuss(oAjax.responseText);
            }    
            else
            {
                fnOnFail(oAjax.status);
            }
        }
    
    };
    
    
    //4.发送数据  真对的是post方式
    
    oAjax.send(null);

}

function ajaxPost(sUrl, data, fnOnScuss, fnOnFail)
{
    //1.创建ajax对象

    var oAjax = null;
    
    if(window.ActiveXObject)
    {
        oAjax = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {
        oAjax = new XMLHttpRequest();
    }
    
    //2.连接服务器 :第一个参数:请求的方式 第二个参数:请求的地址 第三个参数:是不是异步的
    
    oAjax.open('POST', sUrl, true);
    
    //3.监听服务器 : responseText(数据库返回的数据)
    
    oAjax.onreadystatechange = function()
    {
        if(oAjax.readyState == 4)
        {
        
            if(oAjax.status == 200)        //OK
            {
                fnOnScuss(oAjax.responseText);
            }    
            else
            {
                fnOnFail(oAjax.status);
            }
        }
    };
    
    //POST方式必须设置请求头
    oAjax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    
    
    //4.发送数据  真对的是post方式
    
    oAjax.send(data);
}

ajax.js调用

URL会被缓存,所以在地址后加上参数t,值为当前计算机时间( new Date().getTime() ),每次请求的地址就会不一样,计算机就不会缓存地址。

ajax('baidu.php?user=' + oTxt.value + '&t=' + new Date().getTime(), function (str) {
    alert('请求成功:' + str);
}, function (status) {
    alert('请求失败:' + status);
});

JSONP操作

JSONP跨域
ajax :XMLHttpRequest() 对象是不允许跨域的
script 允许跨域,所以跨域操作用script对象

实现原理
JsonP的就是JSON Padding的缩写,它的原理也是非常简单的,利用了script标签的src属性可以链接任何域下的文件的方法,来链接服务器端的一个代理,从而实现了跨域调用数据的方式。

实现流程
1. 动态创建JS文件,请求src地址中约定回调函数名称。
2. 服务端接收请求后直接返回可执行的JavaScript函数调用或者JavaScript对象,例如JSON对象。
3. 执行回调函数。

示例
function createJs(sUrl)
{
    var oScript = document.createElement('script');
    oScript.type = 'text/javascript';
    oScript.src = sUrl;
    document.getElementsByTagName('head')[0].appendChild(oScript);
}

createJs('http://suggestion.baidu.com/su?wd='+encodeURI('潘家园')+'&p=3&cb=cbKey&t='+new Date().getTime());

function cbKey(json)
{
    alert(json.q);
}

运动框架

完美运动框架 ( move.js )

function startMove(obj, json, fn)
{
    clearInterval(obj.timer);
    
    obj.timer = setInterval(function () {
        var bFlag = true;
        
        for(var attr in json)
        {
            var iCur = 0;
            
            if(attr == 'opacity')
            {
                iCur = Math.round(parseFloat(getStyle(obj, attr)) * 100);    
            }
            else if(attr == 'scroll')
            {
                iCur = getScroll();    
            }
            else
            {
                iCur = parseInt(getStyle(obj, attr));    
            }
            
            var iSpeed = (json[attr] - iCur) / 8;
            iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) :Math.floor(iSpeed);
            
            if(attr == 'opacity')
            {
                obj.style.filter = 'alpha(opacity=' + (iSpeed + iCur) + ')';
                obj.style.opacity = (iSpeed + iCur) / 100;    
            }
            else if(attr == 'scroll')
            {
                document.documentElement.scrollTop = document.body.scrollTop = iSpeed + iCur;    
            }
            else
            {
                obj.style[attr] = (iSpeed + iCur) + 'px';    
            }
            
            if(json[attr] != iCur)
            {
                bFlag = false;    
            }
        }
        
        if(bFlag)
        {
            clearInterval(obj.timer);
            if(fn)
            {
                fn.call(obj);    
            }
        }
    }, 30);    
}

function getStyle(obj, attr)
{
    if(obj.currentStyle)
    {
        return obj.currentStyle[attr];    
    }
    else
    {
        return getComputedStyle(obj, false)[attr];    
    }
}

function getScroll()
{
    return document.documentElement.scrollTop || document.body.scrollTop;    
}

调用move.js

startMove(obj, {left:100, top:100, opacity:50}, function () {
    startMove(obj, {opacity:100});
});

面向对象

工厂方式
1. 创建一个构造函数
2. 方法一:构造函数中创建一个对象,给对象添加属性、函数,最后返回对象,方法二:不创建对象,用this指针添加属性、函数,不返回对象。

示例

function CreatePerson(name)
{
    var obj = new Object();
    
    obj.name = name;
    
    obj.showName = function()
    {
        alert(obj.name);
    };

    return obj;
}

function CreatePerson(name)
{
    this.name = name;
    
    this.showName = function()
    {
        alert(this.name);
    };    
    
}

var person = new CreatePerson('Baie');
person.showName();

命名空间


为了解决多个程序之间起冲突

1. 创建一个空的json对象
2. 在此对象中加入另外的json对象

例如
var baie = {};
baie.libs = {
    init:function () {},
    move:function () {}
};

baie.fx = {
    init:function () {},
    move:function () {}
};

调用
baie.libs.init();
baie.fx.init();

JSON改写原型 ( 单体模式 )

CreateFunction.prototype = {
    init:function () {
        alert('function init() {}');
    },
    move:function () {
        alert('function move() {}');
    }
}

hasOwnProperty

object.hasOwnProperty(proName)
返回一个布尔值,指出一个对象是否具有指定名称的属性。

参数

object

必选项。一个对象的实例。

proName

必选项。一个属性名称的字符串值。

说明

如果 object 具有指定名称的属性,那么 hasOwnProperty 方法返回 true;反之则返回 false。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。

示例:( 拷贝对象obj2给obj1 )
function copy(obj1, obj2)
{
    for(var attr in obj2)
    {
        if(obj2.hasOwnProperty(attr))
        {
            obj1[attr] = obj2[attr];
        }
    }
}

constructor

属性返回对创建此对象的数组函数的引用。

示例:

var test=new Array();

if(test.constructor == Array)
{
    document.write("This is an Array");
}

if(test.constructor == Boolean)
{
    document.write("This is a Boolean");
}

用constructor继承

1. 创建一个构造函数 A
2. 新建一个空函数 B        
3. 新建一个A的实例给B的原型
4. B.constructor = B;

示例:

function A(a, b)
{
    this.a=a;
    this.b=b
};

function B() {};
B.pototype=new A;
B.consturtor=B

面向对象继承

继承函数步骤

1. 在子函数中的构造函数中,父级函数.call(this, 参数).
2. for in 循环 原型链。

示例:

function CreateDrag() {
    this.oDiv = null;
    this.disX = 0;
    this.disY = 0;
};

CreateDrag.prototype.init = function (opt) {
    //opt为初始化中的json
    var _this = this;

    this.oDiv = document.getElementById(opt.id);
    this.oDiv.onmousedown = function (ev) {
        var oEvent = ev || event;
        _this.fnDown(oEvent);
    };
};

//继承函数
function Drag(id)
{
    //调用父级函数CreateDrag(),this指向Drag()创建的对象,使CreateDrag在Drag()函数中运行。
    CreateDrag.call(this, id);
    CreateDrag.prototype.init.call(this, id);
}

//复制原型链
for(var i in CreateDrag.prototype)
{
    Drag.prototype[i] = CreateDrag.prototype[i];
}

instanceof

判断一个对象是否是一个类的实例

示例
[] instanceof Array;
'Hellow World' instanceof String;
888 instanceof Number;

判断对象是否为数组

正常应用的情况下,instanceof确实没问题,不过如果在页面有iFrame的情况下就会出错了,即有个A页面定义了一个数组a,页面又嵌套了一个iFrame,在iFrame里面通过 top.a instanceof Array, 是返回false的。

正确做法
Object.prototype.toString.call(对象);


原型链式调用

1. 原型写成JSON形式。
2. 函数内返回 this 指针,不返回this指针则原型链调用结束。

<script>
window.onload = function () {
    var obj = new CreateLink();
    obj.setColor().setSize();
};

function CreateLink()
{
    this.setting = {};
}

//链式操作函数需返回this

CreateLink.prototype = {
        setColor:    function () {
            alert('调用setColor函数');    
            return this;
        },
        setSize:    function () {
            alert('调用setSize函数');
            return this;
        }    
};
</sctipt>


面向对象多态

步骤

1. 构造函数中设置this.setting = {}; json类型数据,并初始化。
2. CreateDrag.prototype.init原型中用自定义copy方法copy(this.setting, opt)属性。
3. 在其它原型函数中调用this.setting中的初始化属性、函数。

示例

function CreateDrag() {
    this.oDiv = null;
    this.disX = 0;
    this.disY = 0;

    //多态步骤1
    //设置构造函数中的初始化各属性
    this.setting = {
        onDown:function () {},
        onUp:function () {},
        left:false,
        top:false
    };
};

CreateDrag.prototype.init = function (opt) {
    //opt为初始化中的json
    var _this = this;
    
    //多态步骤2
    //复制初始化中的json各属性给构造函数中的setting中的各属性
    copy(this.setting, opt);

    this.oDiv = document.getElementById(opt.id);
    this.oDiv.onmousedown = function (ev) {
        var oEvent = ev || event;
        //多态步骤3
        //如果初始化中设置了fnDown函数则调用
        _this.setting.onDown();
        _this.fnDown(oEvent);
    };
};

function copy(obj1, obj2)
{
    for(var attr in obj2)
    {
        if(obj2.hasOwnProperty(attr))
        {
            obj1[attr] = obj2[attr];
        }
    }
}
 

正则表达式

字符串方法

str.search('b'));      //查找元素在字符串中的位置,如果没找到-1
str.substring(1, 3);     //第一个参数是其实位置,第二个参数是结束位置(不包括结束位)
str.charAt(2);      //位置对应的字符
str.split('b');        //分割字符串为数组

正则方法

str.match(/\d+/g);            //返回匹配的结果
正则.test(字符串);            //找到指定的正则在字符串中出现过没有,如果出现过true 没有没出现过false
字符串.search(正则);            //找在字符串里的位置
字符串.replace(正则, 替换字符串);    //替换内容

示例

获取类名相同的元素
function getByClass(oParent, sClass)
{
    var result = [];
    var aEle = document.getElementsByTagName('*');
    var re = new RegExp('\\b' + sClass + '\\b','i');
        
    for(var i = 0; i < aEle.length; i++)
    {
        if(re.test(aEle[i].className))
        {
            result.push(aEle[i]);
        }
    }        
    return result;
}

去掉前后空格
function trim(str)
{
    var re = /^\s+|\s+$/g;
        
    return str.replace(re,'');
}

转义字符

.(点)        任意字符
\d        数字
\D        非数字
\w        字母
\W        非字母
\s        空白字符
\S        非空白字符
\b        分隔符

[]        满足[]内任一字符即可。

|        或,满足 ‘|’ 两边任意一个即可。

示例
var re = \^(139|138|135)(\d{8})$\;

忽略大小写:    i——ignore
全局匹配:    g——global

^        在[]内代表除[]内任意字符,在[]外代表起始位置
$        代表结束位置

示例

去除首尾空格
var re = /^\s+|\s+$/g;

 

量词

{n,m}        最少出现N次,最多出现M次

\d{5,9}        出现5次至9次数字

{5,}          最少出现5次以上
{5}           只能出现5次        

+ -> {1,}    至少出现一次
* -> {0,}    至少出现零次
? -> {0,1}     至少出现一次或零次

常见正则

匹配中文:[\u4e00-\u9fa5]

行首行尾空格:^\s*|\s*$

Email:^\w+@[a-z0-9]+(\.[a-z]+){1,3}$

网址:[a-zA-z]+://[^\s]*

QQ号:[1-9][0-9]{4,}

邮政编码:[1-9]\d{5}

身份证:[1-9]\d{14}|[1-9]\d{17}|[1-9]\d{16}x


JavaScript优化

事件源 ( 事件代理 )

嵌套关系下,将子元素的事件转移到父级元素的身上,减少元素枚举,这样效率会提高。

示例
var oUl = document.getElementsByTagName('ul')[0];
oUl.onclick = function (ev) {
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    
    if(target.tagName='li')
    {
        target.style.background = 'red';
    }
};

 


文档碎片

将元素放入文档碎片后一次渲染,这样会减少浏览器渲染,提高效率。

示例
var arrText = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];

var oFragment = document.createDocumentFragment();

for(var i = 0; i < arrText.length; i++)
{
    var oP = document.createElement("p");
    oP.innerHTML = arrText[i];   
    oFragment.appendChild(oP);
}

document.body.appendChild(oFragment);


下面是一些关于客户端JS性能的一些优化的小技巧

1. [顶]关于JS的循环,循环是一种常用的流程控制。JS提供了三种循环:for(;;)、while()、for(in)。在这三种循环中 for(in)的效率最差,因为它需要查询Hash键,因此应尽量少用for(in)循环,for(;;)、while()循环的性能基本持平。当然,推 荐使用for循环,如果循环变量递增或递减,不要单独对循环变量赋值,而应该使用嵌套的++或--运算符。

2.如果需要遍历数组,应该先缓存数组长度,将数组长度放入局部变量中,避免多次查询数组长度。

3.局部变量的访问速度要比全局变量的访问速度更快,因为全局变量其实是window对象的成员,而局部变量是放在函数的栈里的。

4.尽量少使用eval,每次使用eval需要消耗大量时间,这时候使用JS所支持的闭包可以实现函数模板。

5. 尽量避免对象的嵌套查询,对于obj1.obj2.obj3.obj4这个语句,需要进行至少3次查询操作,先检查obj1中是否包含 obj2,再检查obj2中是否包含obj3,然后检查obj3中是否包含obj4...这不是一个好策略。应该尽量利用局部变量,将obj4以局部变量 保存,从而避免嵌套查询。

6.使运算符时,尽量使用+=,-=、*=、\=等运算符号,而不是直接进行赋值运算。

7. [顶]当需要将数字转换成字符时,采用如下方式:"" + 1。从性能上来看,将数字转换成字符时,有如下公式:("" +) > String() > .toString() > new String()。String()属于内部函数,所以速度很快。而.toString()要查询原型中的函数,所以速度逊色一些,new String()需要重新创建一个字符串对象,速度最慢。

8.[顶]当需要将浮点数转换成整型时,应该使用Math.floor()或者 Math.round()。而不是使用parseInt(),该方法用于将字符串转换成数字。而且Math是内部对象,所以Math.floor()其实并没有多少查询方法和调用时间,速度是最快的。

9.尽量使用JSON格式来创建对象,而不是var obj=new Object()方法。因为前者是直接复制,而后者需要调用构造器,因而前者的性能更好。

10. 当需要使用数组时,也尽量使用JSON格式的语法,即直接使用如下语法定义数组:[parrm,param,param...],而不是采用 new Array(parrm,param,param...)这种语法。因为使用JSON格式的语法是引擎直接解释的。而后者则需要调用Array的构造器。

11.[顶]对字符串进行循环操作,例如替换、查找,就使用正则表达式。因为JS的循环速度比较慢,而正则表达式的操作是用C写成的API,性能比较好。

最后有一个基本原则,对于大的JS对象,因为创建时时间和空间的开销都比较大,因此应该尽量考虑采用缓存。


大家有什么问题或技术上的想法可以在此与大家分享,也可以加入前端爱好者QQ群(141999928)一起学习进步:【幸凡前端技术交流群】
0

如果您觉得本文的内容对您的学习有所帮助,捐赠与共勉,支付宝(左)或微信(右)

阅读全文内容关闭