JavaScript是一门弱语言,她使用起来不像C/C++那样有十分繁琐的内存管理、类型定义等,所以学习JavaScript的门槛相对来说也比较低。门槛低并不意味着这门语言很简单,我们在使用的时候会遇到各种千奇百怪的问题,有些是因为浏览器的兼容性引起的,有些是因为JS语法本身所引起的,还有些是因为ECMAScript标准的改变而引起的,总之,这样的问题很多,下面列举

几个比较容易忽略的点

  1. switch的case判断

var t = event.keyCode;
switch (t) {
case '65':
alert("Yay!");
break;
}

  当keycode为65时,你会发现,咦?怎么木有alert! 这里需要明确的是,switch在判断的时候使用的是全等号“===”,全等号在比较的时候首先看数据类型是不是一样的,而在这里,t是Number类型,而'65'是String。

  2. 严格模式下this≠window

"use strict";
var global = (function() {
console.log(this); //undefined
})();

  有时候我们需要用global来缓存this这个全局环境(可能是window,也可能是其他的,比如在Worker中没有window对象,用self代表Global),但是在严格模式下函数作用域返回的this为undefined,一般,我们可以采用如下方式获取到Global对象:

"use strict";
var global = (function() {
var t = new Function("return this")();
console.log(t);
})();

或者:

"use strict";
var global = (function() {
var t = window.eval("this");
console.log(t);
})();

  因为new Function是在全局作用域上执行的,所以返回的是Global对象,下面的eval需要一起注意,eval前如果不交window,那它便处于function作用域中(javascript利用function里分隔作用域),自然不会返回window或者全局对象。使用Function要注意一点:

(function () {
var local = 1;
new Function("console.log(typeof local);")(); // logs undefined
}());

  new Function工作在Global作用域链下,所以是访问不到匿名函数中local的~

  3. 变量提升(Hoisting)

var t = "global";
function foo(){
console.log(t); //undefined
return;
   var t = "local";
}

  这是一个老生常谈的问题,var最好不好到处散布。所谓的变量提升,在这里存在两个作用域,一个是Global作用域,他下面有t和foo这两个变量,而foo指向的是foo作用域,foo作用域下有一个t变量,画个图演示下吧

[Global Scope]
|----- t [String] undefined -> "global"
|----- foo [Reference] [foo Scope] [foo Scope]
|----- t [String] undefined -> "local"

  刚进入全局作用域链的时候,程序扫描到t和foo两个变量,于是给这个t赋值为undefined,扫面完了之后,看到t有值,于是给赋值”global“,foo指向[foo Scope],于是进入[foo Scope],继续扫描函数作用域链下的变量,发现目标t之后,赋值为undefined,在console.log时,是这样的:

var t = "global";
function foo(){
var t; // 等同于 -> var t = undefined;
    console.log(t); //undefined 
return;  
var t = "local";
}

  上面的例子写不写return结果都是一样的,加return,只是为了更好的表达变量提升这个动作的存在。一般比较推荐的变量定义方式:

function foo(a, b, c) {
var x = 1,
bar,
baz = "something";
}

  一个var,后边连着一串变量的定义。

附:javascript严格模式下要注意的地方(转自次碳酸钴

1. 变量必须声明才能使用

"use strict";
a=1; //缺少var语句做声明,因此报错
"use strict";
var a=b=1; //错误 b未声明

2. 函数声明语句(不包括表达式)不允许在普通代码块(不包括闭包)中使用

"use strict";
(function(){
//闭包中是允许使用函数声明语句的
function func(){};
})();
{
var f=function(){}; //函数声明表达式允许
function func(){}; //函数声明语句在普通闭包中,错误
};

3. 闭包内的this不指向Global对象

"use strict";
(function(){
alert(this); //输出undefined
})();

4. 对象属性和函数形参不能重复声明

"use strict";
var o={a:1,a:1};
//这个对象定义了两个a属性,因此报错
"use strict";
function func(a,a){};
//这个函数的两个形参都是a,因此报错

5. eval拥有类似闭包的作用域

"use strict";
var a=1,b=1;
eval("var a=2");
window.eval("var b=2");
alert(a); //输出1 因为运行的a变成了eval作用域的局部变量
alert(b); //输出2 window.eval依然是全局作用域

6. callee和caller属性无法使用

"use strict";
function func(){
return arguments.callee; //错误 callee无法使用
};
func();

7. with语句无法使用

"use strict";
with({});

8. 八进制数字常量无法使用

"use strict";
var a=0999; //十进制,可以使用
var b=0123; //八禁止,无法使用

9. 普通模式下的一些无效操作变成错误

"use strict";
var a=1;
delete a;
//错误 无法删除var声明的变量
"use strict";
var o={get a(){}};
o.a=1;
//错误 给只读属性赋值

简单总结这么多,推荐“次碳酸钴”童鞋的博客,细致入微、内容深刻,博客入口:http://www.web-tinker.com

关于JavaScript strict mode的详细介绍,请移步:MDN Strict_mode

JavaScript中需要注意的几个问题的更多相关文章

  1. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  2. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  3. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

  4. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  5. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  6. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  7. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  8. 简单分析JavaScript中的面向对象

    初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...

  9. Javascript中的valueOf与toString

    基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...

  10. 关于javascript中的this关键字

    this是非常强大的一个关键字,但是如果你不了解它,可能很难正确的使用它. 下面我解释一下如果在事件处理中使用this. 首先我们讨论一下下面这个函数中的this关联到什么. function doS ...

随机推荐

  1. Thrift 2中get用法的详细解析

    Thrift2相比于Thrift 1改动较大,这里不去描述改动的地方,但是它的改动确实比Thrift1方便了很多.但是不能理解的是Thrift2网上的资料和文档相当的少,就以Thrift2操作Hbas ...

  2. jsp文件引入js文件的方式(项目部署于web容器中)

    在页面中引入javascript文件的方式是多种多样的,本文介绍两种. 通过<script>标签插入js文件 通过这种方式引入的js,写对js文件和jsp文件的路径很重要.下面给出一个项目 ...

  3. 搭建高可用mongodb集群(三)—— 深入副本集内部机制

    在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...

  4. C# 解析 Json

    C# 解析 json JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的 ...

  5. 解析jquery获取父窗口的元素

    ("#父窗口元素ID",window.parent.document); 对应javascript版本为window.parent.document.getElementByIdx ...

  6. css3中的字体样式

    text-overform:ellipsis省略号/clip裁剪. overform:hidden溢出隐藏文字. 但是text-overflow只是用来说明文字溢出时用什么方式显示,要实现溢出时产生省 ...

  7. ORA-12543: TNS:destination host unreachable

    在连接Oracle数据库时,如果使用Tnsnames.ora中配置的数据源名称有时会报 ORA-12543: TNS:destination host unreachable 异常,比如:在Tnsna ...

  8. [转]SQL Server字符串处理函数大全

    select语句中只能使用sql函数对字段进行操作(链接sql server), select 字段1 from 表1 where 字段1.IndexOf("云")=1;这条语句不 ...

  9. Lessons Learned 1(敏捷项目中的变更影响分析)

    问题/现象: 业务信息流转的某些环节,会向相关人员发送通知邮件,邮件中附带有链接,供相关人员进入察看或处理业务.客户要求邮件中的链接,需要进行限制,只有特定人员才能进入处理或察看.总管想了想,应道没问 ...

  10. 算法入门笔记------------Day3

    主要是复习前面的基本内容,以及函数的概念 组合数 #include<stdio.h> int f(int n) { int m=1; for(int i=1;i<=n;i++) m* ...