JavaScript:打破所有规则 错误的东西也许是有用的作者:协策网络-客服部 标签:外贸网站建设 日期:2012年10月10日 类别:行业动态 |
||||
北京时间今天凌晨,来自Twitter的前端工程师Angus Crol,在柏林举办的JSConf会议上,进行了题为”Break all the Rulez“的演讲,主要讲了一些我们通常认为是错误的不该使用的东西,其实是有用的.本文最下面有演讲用的slides.远在美国的JavaScript之父看了slides也说:我同意其中大部分观点(看来还是有问题?). 下面我把要点简单翻译一下,不做扩展解释. with语句 为什么不去使用它? 1.意外的运行结果,可能隐式创建全局变量 2.闭包作用域解析过多消耗 3.后期编译 有人说,ES5的严格模式可以防止隐式创建全局变量(不用var),这样能减少with的一个问题.但是… 严格模式也不能使用with啊. 为什么说它是有用的? 1.构建浏览器开发者工具
//Chrome Developer Tools IS._evaluateOn = function (evalFunction, obj, expression) { IS._ensureCommandLineAPIInstalled(); expression = "with (window._inspectorCommandLineAPI) {\ with (window) { " + expression + " } }" ; return evalFunction.call(obj, expression); } 2.模拟块级作用域
//是的,还是这个老掉牙的问题 var addHandlers = function (nodes) { for ( var i = 0; i < nodes.length; i++) { nodes[i].onclick = function (e) {alert(i);} } }; //你可以通过在外面包一个函数来解决 var addHandlers = function (nodes) { for ( var i = 0; i < nodes.length; i++) { nodes[i].onclick = function (i) { return function (e) {alert(i);}; }(i); } }; //或者使用'with'来模拟块级作用域 var addHandlers = function (nodes) { for ( var i = 0; i < nodes.length; i++) { with ({i:i}) { nodes[i].onclick = function (e) {alert(i);} } } }; eval语句 为什么不去使用它? 1.代码注入 2.无法进行闭包优化 3.后期编译 为什么说它是有用的? 1. JSON.parse不可用的时候 有人在Stack Overflow上说: “JavaScript的eval是不安全的,使用json.org上的JSON解析器来解析JSON” 还有人说: “不要使用eval来解析JSON!用道格拉斯写的json2.js!” 可是:
// From JSON2.js if (/^[\],:{}\s]*$/ .test(text.replace( /*regEx*/ , '@' ) .replace( /*regEx*/ , ']' ) .replace( /*regEx*/ , '' ))) { j = eval( '(' + text + ')' ); } 2.浏览器的JavaScript控制台都是用eval实现的 在Webkit控制台或JSBin中执行下面的代码
>( function () { console.log(String(arguments.callee.caller)) })() function eval() { [native code] } John Resig说过: “eval和with是被轻视的,被误用的,被大部分JavaScript程序员公然谴责的,但如果能正确使用的话,可以用它们写出一些奇妙的,无法用其他功能实现的代码” Function构造函数 为什么说它是有用的? 1.代码运行在可预见的作用域内 2.只能动态创建全局变量 3.不存在闭包优化的问题 用在了什么地方? 1. jQuery的parseJSON
// jQuery parseJSON // Logic borrowed from http://json.org/json2.js if (rvalidchars.test(data.replace(rvalidescape, "@" ) .replace( rvalidtokens, "]" ) .replace( rvalidbraces, "" ))) { return ( new Function( "return " + data ) )(); } 2.Underscore.js的字符串内插
//from _.template // If a variable is not specified, // place data values in local scope. if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n' ; //.. var render = new Function( settings.variable || 'obj' , '_' , source); ==运算符 为什么不去使用它? 1.强制将两边的操作数转换为相同类型 为什么说它是有用的? 1.强制将两边的操作数转换为相同类型 2.undefined == null
//这样写是不是很麻烦 if ((x === null ) || (x === undefined)) //完全可以下面这样写 if (x == null ) 3.当两边的操作数类型明显相同时使用
typeof thing == "function" ; //typeof运算符肯定返回字符串 myArray.length == 2; //length属性肯定返回数字 myString.indexOf( 'x' ) == 0; //indeOf方法肯定返回数字 真值不一定==true,假值不一定==false
if ( "potato" ) { "potato" == true ; //false } Array构造函数 为什么不去使用它?
1.new Array()也是evil的?JS 为什么说它是有用的?
//From prototype.js extension of //String.prototype function times(count) { return count < 1 ? '' : new Array(count + 1).join( this ); } 'me' .times(10); //"memememememememememe" 其他 不要扩展原生的原型对象 (es 5 shims都这么干) 在for/in遍历时总要使用hasOwnProperty (在没有扩展对象原型的前提下没有必要这么做) 把所有的var语句放在顶部 (for语句还是放在初始化表达式中好) 要在调用函数之前先声明函数 (在优先考虑实现细节时使用) 不要使用逗号运算符 (在使用多个表达式时的时候可以使用) 使用parseInt时总要把第二个参数指定为10 (除非字符串以‘0’或‘x’开头,否则没必要) 译者注 上面说了这么多,我自己也想到一个被误解的东西,那就是escape.网上有不少人说:“不要使用escape”. 为什么说它是有用的? 1.escape转义的字符更多,有时候需要转义后两个函数不转义的字符.
可以推导出UTF16ToUTF8(str) === 然后就能用在base64编码的时候,比网上看到的那些简单多了吧.注意btoa和atob有兼容问题.
function base64Encode(str) { return btoa(unescape(encodeURIComponent(str))); } function base64Decode(str) { return decodeURIComponent(escape(atob(str))); } 您可能感兴趣的文章推荐 |
||||
|