JavaScript打破所有规则
来自Twitter的前端工程师Angus Croll,在柏林举办的JSConf会议上,进行了题为”Break all the Rulez“的演讲。主要讲了一些我们通常认为是错误的不该使用的东西,其实是有用的。Angus Croll 演讲用的讲稿(链接),远在美国的JavaScript之父看后也说同意其中大部分观点(看来还是有问题?)。
下面我把要点简单翻译一下,不做扩展解释.
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的?JSLint也推荐使用[].
为什么说它是有用的?
//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转义的字符更多,有时候需要转义后两个函数不转义的字符.
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有兼容问题.
function base64Encode(str) {
return btoa(unescape(encodeURIComponent(str)));
}
function base64Decode(str) {
return decodeURIComponent(escape(atob(str)));
}

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数
