JavaScript是一门弱语言,她使用起来不像C/C++那样有十分繁琐的内存管理、类型定义等,所以学习JavaScript的门槛相对来说也比较低。门槛低并不意味着这门语言很简单,我们在使用的时候会遇到各种千奇百怪的问题,有些是因为浏览器的兼容性引起的,有些是因为JS语法本身所引起的,还有些是因为ECMAScript标准的改变而引起的,总之,这样的问题很多,下面列举
几个比较容易忽略的点
1. switch的case判断
var t = event.keyCode; |
当keycode为65时,你会发现,咦?怎么木有alert! 这里需要明确的是,switch在判断的时候使用的是全等号\===",全等号在比较的时候首先看数据类型是不是一样的,而在这里,t是Number类型,而'65'是String。
2. 严格模式下this≠window
; |
有时候我们需要用global来缓存this这个全局环境(可能是window,也可能是其他的,比如在Worker中没有window对象,用self代表Global),但是在严格模式下函数作用域返回的this为undefined,一般,我们可以采用如下方式获取到Global对象:
; |
或者:
; |
因为new Function是在全局作用域上执行的,所以返回的是Global对象,下面的eval需要一起注意,eval前如果不交window,那它便处于function作用域中(javascript利用function里分隔作用域),自然不会返回window或者全局对象。使用Function要注意一点:
(function () { |
new Function工作在Global作用域链下,所以是访问不到匿名函数中local的~
3. 变量提升(Hoisting)
var t = "global"; |
这是一个老生常谈的问题,var最好不好到处散布。所谓的变量提升,在这里存在两个作用域,一个是Global作用域,他下面有t和foo这两个变量,而foo指向的是foo作用域,foo作用域下有一个t变量,画个图演示下吧
[Global Scope] |
刚进入全局作用域链的时候,程序扫描到t和foo两个变量,于是给这个t赋值为undefined,扫面完了之后,看到t有值,于是给赋值"global\,foo指向[foo Scope],于是进入[foo Scope],继续扫描函数作用域链下的变量,发现目标t之后,赋值为undefined,在console.log时,是这样的:
var t = "global"; |
上面的例子写不写return结果都是一样的,加return,只是为了更好的表达变量提升这个动作的存在。一般比较推荐的变量定义方式:
function foo(a, b, c) { |
一个var,后边连着一串变量的定义。
附:javascript严格模式下要注意的地方(转自次碳酸钴)
1. 变量必须声明才能使用
; |
; |
2. 函数声明语句(不包括表达式)不允许在普通代码块(不包括闭包)中使用
; |
3. 闭包内的this不指向Global对象
; |
4. 对象属性和函数形参不能重复声明
; |
; |
5. eval拥有类似闭包的作用域
; |
6. callee和caller属性无法使用
; |
7. with语句无法使用
; |
8. 八进制数字常量无法使用
; |
9. 普通模式下的一些无效操作变成错误
; |
; |
简单总结这么多,推荐\次碳酸钴"童鞋的博客,细致入微、内容深刻,博客入口:http://www.web-tinker.com
关于JavaScript strict mode的详细介绍,请移步:MDN Strict_mode