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对象,因为创建时时间和空间的开销都比较大,因此应该尽量考虑采用缓存。