JavaScript中需要注意的几个问题
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中需要注意的几个问题的更多相关文章
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- javascript中的this与函数讲解
前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
- javascript中的操作符详解1
好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...
- 掌握javascript中的最基础数据结构-----数组
这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...
- javascript中变量提升的理解
网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...
- 简单分析JavaScript中的面向对象
初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...
- Javascript中的valueOf与toString
基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...
- 关于javascript中的this关键字
this是非常强大的一个关键字,但是如果你不了解它,可能很难正确的使用它. 下面我解释一下如果在事件处理中使用this. 首先我们讨论一下下面这个函数中的this关联到什么. function doS ...
随机推荐
- win8 vs2010 openni2 配置
打开一个新项目或者已存在的项目用以使用 OpenNI 在Visual Studio 菜单中, 打开项目菜单,选择项目属性. 在C/C++ 选项卡中, 在"常规" 下, 选择 &q ...
- css鼠标手型cursor中hand与pointer
css鼠标手型cursor中hand与pointer Example:CSS鼠标手型效果 <a href="#" style="cursor:hand"& ...
- webpack+react配置
$ npm install -g webpack $ npm install -g webpack-dev-server如果遇到类似 EACESS 错误,则需要用超级用户的模式运行 $ sudo np ...
- Sql Server 常用操作
--DDL触发器CREATE TRIGGER [TR_create_drop_alter_Table] ON DATABASE FOR CREATE_TABLE,DROP_table,ALTER_ ...
- Android数据库加密之sqlciher方案
版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/6241964.html 前言 大家好,我是Cavalier ...
- 关于MYSQL四种引擎
你能用的数据库引擎取决于mysql在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另外两种类型INNO ...
- C# 如何给sql数据库的日期字段插入空值
在C#中声明日期变量时用SqlDateTime类型,引用:using System.Data.SqlTypes; 例子:user.AbortDate = SqlDateTime.Null;
- JavaScript对UNIX时间戳的转换
<script type="text/javascript"> var timestamp = '1479886513'; var d = new Date(times ...
- 黑马程序员-懒加载 lazy loading
懒加载:延迟加载,当程序启动时不加载资源,当程序需要这些资源时再去加载.需要的时候再加载的一种方式,能够减少内存的占用,效率高.其本质是重写get方法. 背景:由于ios内存有限,如果我们一次性将所有 ...
- 近期C#项目中总结
1. 读写文件操作 using (file = new System.IO.StreamReader(inputfile)) { using (outfile = new System.IO.Stre ...