JavaScript:打破所有规则

北京时间今天凌晨,来自Twitter的前端工程师Angus Crol,在柏林举办的JSConf会议上,进行了题为"Break all the Rulez"的演讲,主要讲了一些我们通常认为是错误的不该使用的东西,其实是有用的.本文最下面有演讲用的slides.远在美国的JavaScript之父看了slides也说:我同意其中大部分观点(看来还是有问题?).

康县网站建设公司创新互联,康县网站设计制作,有大型网站制作公司丰富经验。已为康县超过千家提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的康县做网站的公司定做!

下面我把要点简单翻译一下,不做扩展解释.

with语句

为什么不去使用它?

1.意外的运行结果,可能隐式创建全局变量

2.闭包作用域解析过多消耗

3.后期编译

有人说,ES5的严格模式可以防止隐式创建全局变量(不用var),这样能减少with的一个问题.但是...

严格模式也不能使用with啊.

为什么说它是有用的?

1.构建浏览器开发者工具

 

 
 
 
 
  1. //Chrome Developer Tools  
  2. IS._evaluateOn =  
  3.   function(evalFunction, obj, expression) {  
  4.     IS._ensureCommandLineAPIInstalled();  
  5.     expression =  
  6.       "with (window._inspectorCommandLineAPI) {\  
  7.         with (window) { " + expression + " } }";  
  8.     return evalFunction.call(obj, expression);  

2.模拟块级作用域

     

 
 
 
 
  1. //是的,还是这个老掉牙的问题  
  2. var addHandlers = function(nodes) {  
  3.   for (var i = 0; i < nodes.length; i++) {  
  4.     nodes[i].onclick =  
  5.       function(e) {alert(i);}  
  6.   }  
  7. }; 
 
 
 
 
  1. //你可以通过在外面包一个函数来解决  
  2. var addHandlers = function(nodes) {  
  3.   for (var i = 0; i < nodes.length; i++) {  
  4.     nodes[i].onclick = function(i) {  
  5.       return function(e) {alert(i);};  
  6.     }(i);  
  7.   }  
  8. }; 
 
 
 
 
  1. //或者使用'with'来模拟块级作用域  
  2. var addHandlers = function(nodes) {  
  3.   for (var i = 0; i < nodes.length; i++) {  
  4.     with ({i:i}) {  
  5.       nodes[i].onclick =  
  6.         function(e) {alert(i);}  
  7.     }  
  8.   }  
  9. }; 

#p#

eval语句

为什么不去使用它?

1.代码注入

2.无法进行闭包优化

3.后期编译

为什么说它是有用的?

1. JSON.parse不可用的时候

有人在Stack Overflow上说:

“JavaScript的eval是不安全的,使用json.org上的JSON解析器来解析JSON”

还有人说:

“不要使用eval来解析JSON!用道格拉斯写的json2.js!”

可是:

 

 
 
 
 
  1. // From JSON2.jsif (/^[\],:{}\s]*$/  .test(text.replace(/*regEx*/, '@')  .replace(/*regEx*/, ']')  .replace(/*regEx*/, ''))) {  j = eval('(' + text + ')');} 

2.浏览器的JavaScript控制台都是用eval实现的

在Webkit控制台或JSBin中执行下面的代码

 

 
 
 
 
  1. >(function () {    console.log(String(arguments.callee.caller))})()function eval() {    [native code]} 

John Resig说过:

“eval和with是被轻视的,被误用的,被大部分JavaScript程序员公然谴责的,但如果能正确使用的话,可以用它们写出一些奇妙的,无法用其他功能实现的代码”

Function构造函数

为什么说它是有用的?

1.代码运行在可预见的作用域内

2.只能动态创建全局变量

3.不存在闭包优化的问题

用在了什么地方?

1. jQuery的parseJSON

 

 
 
 
 
  1. // jQuery parseJSON   
  2.  
  3. // Logic borrowed from http://json.org/json2.js  
  4. if (rvalidchars.test(data.replace(rvalidescape,"@")  
  5.   .replace( rvalidtokens,"]")  
  6.   .replace( rvalidbraces,""))) {  
  7.  
  8.   return ( new Function( "return " + data ) )();  

2.Underscore.js的字符串内插

 

 
 
 
 
  1. //from _.template  
  2.  
  3. // If a variable is not specified,  
  4. // place data values in local scope.  
  5. if (!settings.variable)   
  6.   source = 'with(obj||{}){\n' + source + '}\n';  
  7.  
  8. //..  
  9.  
  10. var render = new Function(  
  11.   settings.variable || 'obj', '_', source); 

#p#

==运算符

为什么不去使用它?

1.强制将两边的操作数转换为相同类型

为什么说它是有用的?

1.强制将两边的操作数转换为相同类型

2.undefined == null

 

 
 
 
 
  1. //这样写是不是很麻烦  
  2. if ((x === null) || (x === undefined))  
  3.  
  4. //完全可以下面这样写  
  5. if (x == null)  

3.当两边的操作数类型明显相同时使用

 

 
 
 
 
  1. typeof thing == "function";   //typeof运算符肯定返回字符串  
  2. myArray.length == 2;          //length属性肯定返回数字  
  3. myString.indexOf('x') == 0;   //indeOf方法肯定返回数字 

真值不一定==true,假值不一定==false

 
 
 
 
  1. if ("potato") {  
  2.   "potato" == true;  //false  
  3. }  

 

Array构造函数

为什么不去使用它?

1.new Array()也是evil的?JSLint也推荐使用[].

为什么说它是有用的?

 
 
 
 
  1. //From prototype.js extension of   
  2. //String.prototype  
  3. function times(count) {  
  4.   return count < 1 ?  
  5.     '' : new Array(count + 1).join(this);  
  6. }  
  7. 'me'.times(10); //"memememememememememe" 

 

其他

不要扩展原生的原型对象
(es 5 shims都这么干)
在for/in遍历时总要使用hasOwnProperty
(在没有扩展对象原型的前提下没有必要这么做)
把所有的var语句放在顶部
(for语句还是放在初始化表达式中好)
要在调用函数之前先声明函数
(在优先考虑实现细节时使用)
不要使用逗号运算符
(在使用多个表达式时的时候可以使用)
使用parseInt时总要把第二个参数指定为10
(除非字符串以‘0’或‘x’开头,否则没必要)

#p#

译者注

上面说了这么多,我自己也想到一个被误解的东西,那就是escape.网上有不少人说:"不要使用escape".

为什么说它是有用的?

1.escape转义的字符更多,有时候需要转义后两个函数不转义的字符.

ASCII char escape() encodeURI() encodeURIComponent()
!%21!!
#%23#%23
$%24$%24
&%26&%26
'%27''
(%28((
)%29))
+++%2B
,%2C,%2C
///%2F
:%3A:%3A
;%3B;%3B
=%3D=%3D
?%3F?%3F
@@@%40
~%7E~~

2.将字符串转换为UTF8编码,通常用在base64的时候.

escape相当于是在utf16编码的字符串上转义,encodeURIComponent相当于是先把utf16的字符串转换成utf8编码后再escape.

encodeURIComponent(str) === escape(UTF16ToUTF8(str))

可以推导出UTF16ToUTF8(str) === unescape( encodeURIComponent( str )

然后就能用在base64编码的时候,比网上看到的那些简单多了吧.注意btoa和atob有兼容问题.

 
 
 
 
  1. function base64Encode(str) {  
  2.     return btoa(unescape(encodeURIComponent(str)));  
  3. }  
  4.  
  5. function base64Decode(str) {  
  6.     return decodeURIComponent(escape(atob(str)));  

当前名称:JavaScript:打破所有规则
标题URL:http://www.shufengxianlan.com/qtweb/news37/74587.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联