1.使用Function代替eval
在任何情况下,使用字符串去执行javascript都不是一个好主意,而使用eval更是坏的方案——你没办法去判断这个字符串执行之后是否安全,稍微好点的办法就是用闭包来执行eval或者使用Function(更直观一点)。这样如果不是恶意代码的话,尽可能减少全局变量的个数(如果是恶意代码,把结果放在window内就可以变成全局变量了,所以并没有解决实际问题)
console.log(typeof un); //undefinde console.log(typeof deux); //undefinde console.log(typeof trois); //undefinde var jsstring = "var un=1;console.log(un); console.log(this);"; eval(jsstring); jsstring = "var deux=2;console.log(deux);console.log(this);"; new Function(jsstring)(); jsstring = "var trois=3;console.log(trois);console.log(this);"; (function() { eval(jsstring); }()); console.log(typeof un); //number console.log(typeof deux); //undefinde console.log(typeof trois); //undefinde
2.强制使用构造函数(自调用构造函数)
在javascript的面向对象内,不存在“类”这个东西,只有函数,而只有用了new关键字的函数才能被称为“构造函数”,而我们(或者其他什么人)有可能会忘记使用new关键字或其他原因导致原本应该是“构造函数”的函数被当做普通函数调用
解决方式:采用自调用判断:
function Waffle (){ if(!(this instanceof Waffle)){ return new Waffle(); } this.tastes='yummy'; } var xiaosi1=new Waffle(); var xiaosi2=Waffle(); console.log(xiaosi1.tastes); //yummy console.log(xiaosi2.tastes); //yummy function Waffle2(){ if(!(this instanceof arguments.callee)){ return new arguments.callee(); } this.tastes='yummy'; } var xiaosi3=new Waffle(); var xiaosi4=Waffle(); console.log(xiaosi3.tastes); //yummy console.log(xiaosi4.tastes); //yummy
像上面这样在执行前判断一下是不是作为构造函数使用,如果不是再回调自己是一种很好的实现方法,这样可以保证按照我们想象中的方式调用
ps:顺带一提,arguments.callee属性不被ECMAScript 5的严格模式支持,也不会通过JSLint验证,所以用的时候需要稍微注意一下
3.尽量少使用Array构造函数,仅仅适用于创建重复字符串
使用案例:
var a=new Array(21).join('a'); console.log(a); //aaaaaaaaaaaaaaaaaaaa (20个a)
new Array()仅仅用于这少数情况比较有效果,毕竟js的数组是没有固定长度的,需要注意的是join方法插入的是分隔符,21数组长度的数组分隔符是20个,并且返回的是字符串,不是array
4.检测数组类型
检测数组类型光靠length或者是instanceof并不是十分准确,后者在ie的多框架情况下会出现bug
比较好的检测方式:
Object.prototype.toString.call(array);
返回的字符串在array情况下为[Object Array]。