热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Javascript易错的知识点

2015-06-2119:


忘记var的副作用(Side Effects When Forgetting var)


隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力。

 

●通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。

●无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。

 

这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的:

// 定义三个全局变量

var global_var = 1;

global_novar = 2; // 反面教材

(function () {

global_fromfunc = 3; // 反面教材

}());

 

// 试图删除

delete global_var; // false

delete global_novar; // true

delete global_fromfunc; // true

 

// 测试该删除

typeof global_var; // "number"

typeof global_novar; // "undefined"

typeof global_fromfunc; // "undefined"

在ES5严格模式下,未声明的变量(如在前面的代码片段中的两个反面教材)工作时会抛出一个错误。



访问全局对象(Access to the Global Object)

 

在浏览器中,全局对象可以通过window属性在代码的任何位置访问(除非你做了些比较出格的事情,像是声明了一个名为window的局部变量)。但是在其他环境下,这个方便的属性可能被叫做其他什么东西(甚至在程序中不可用)。如果你需要在没有硬编码的window标识符下访问全局对象,你可以在任何层级的函数作用域中做如下操作:

var global = (function () {

return this;

}());

这种方法可以随时获得全局对象,因为其在函数中被当做函数调用了(不是通过new构造),this总是指向全局对象。实际上这个病不适用于ECMAScript 5严格模式,所以,在严格模式下时,你必须采取不同的形式。例如,你正在开发一个Javascript库,你可以将你的代码包裹在一个即时函数中,然后从全局作用域中,传递一个引用指向this作为你即时函数的参数。



预解析:var散布的问题(Hoisting: A Problem with Scattered vars)

 

Javascript中,你可以在函数的任何位置声明多个var语句,并且它们就好像是在函数顶部声明一样发挥作用,这种行为称为hoisting(悬置/置顶解析/预解析)。当你使用了一个变量,然后不久在函数中又重新声明的话,就可能产生逻辑错误。对于Javascript,只要你的变量是在同一个作用域中(同一函数),它都被当做是声明的,即使是它在var声明前使用的时候。看下面这个例子:

// 反例

myname = "global"; // 全局变量

function func() {

alert(myname); // "undefined"

var myname = "local";

alert(myname); // "local"

}

func();

在这个例子中,你可能会以为第一个alert弹出的是”global”,第二个弹出”loacl”。这种期许是可以理解的,因为在第一个alert的时候,myname未声明,此时函数肯定很自然而然地看全局变量myname,但是,实际上并不是这么工作的。第一个alert会弹出”undefined”是因为myname被当做了函数的局部变量(尽管是之后声明的),所有的变量声明当被悬置到函数的顶部了。因此,为了避免这种混乱,最好是预先声明你想使用的全部变量。

 

上面的代码片段执行的行为可能就像下面这样:

myname = "global"; // global variable

function func() {

var myname; // 等同于 -> var myname = undefined;

alert(myname); // "undefined"

myname = "local";

alert(myname); // "local"}

func();



为了完整,我们再提一提执行层面的稍微复杂点的东西。代码处理分两个阶段,第一阶段是变量,函数声明,以及正常格式的参数创建,这是一个解析和进入上下文的阶段。第二个阶段是代码执行,函数表达式和不合格的标识符(为声明的变量)被创建。但是,出于实用的目的,我们就采用了”hoisting”这个概念,这种ECMAScript标准中并未定义,通常用来描述行为。


for-in循环(for-in Loops)

 

for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”。

 

从技术上将,你可以使用for-in循环数组(因为Javascript中数组也是对象),但这是不推荐的。因为如果数组对象已被自定义的功能增强,就可能发生逻辑错误。另外,在for-in中,属性列表的顺序(序列)是不能保证的。所以最好数组使用正常的for循环,对象使用for-in循环。

 

有个很重要的hasOwnProperty()方法,当遍历对象属性的时候可以过滤掉从原型链上下来的属性。


左花括号的位置(Opening Brace Location)

 

开发人员对于左大括号的位置有着不同的偏好——在同一行或是下一行。

if (true) {

alert("It‘s TRUE!");

}

if (true)

{

alert("It‘s TRUE!");

}

这个实例中,仁者见仁智者见智,但也有个案,括号位置不同会有不同的行为表现。这是因为分号插入机制(semicolon insertion mechanism)——Javascript是不挑剔的,当你选择不使用分号结束一行代码时Javascript会自己帮你补上。这种行为可能会导致麻烦,如当你返回对象字面量,而左括号却在下一行的时候:

// 警告: 意外的返回值

function func() {

return

// 下面代码不执行

{

name : "Batman"

}

}

如果你希望函数返回一个含有name属性的对象,你会惊讶。由于隐含分号,函数返回undefined。前面的代码等价于:

// 警告: 意外的返回值

function func() {

return undefined;

// 下面代码不执行

{

name : "Batman"

}

}



关于分号注:就像使用花括号,你应该总是使用分号,即使他们可由Javascript解析器隐式创建。这不仅促进更科学和更严格的代码,而且有助于解决存有疑惑的地方,就如前面的例子显示。




推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
author-avatar
叶晴琼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有