1、忘记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"

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

// 反例
myname = "global"; // 全局变量
function func() {alert(myname); // "undefined"var myname = "local";alert(myname); // "local"
}
func();
//等价于下面这段代码
myname = "global"; // global variable
function func() {var myname; // 等同于 -> var myname = undefined;alert(myname); // "undefined"myname = "local";alert(myname); // "local"}
func();

for-in循环(for-in Loops)

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

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

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

for (var i in man) {if (man.hasOwnProperty(i)) { // 过滤原型属性或方法console.log(i, ":", man[i]);}
}// 反面例子:
// for-in loop without checking hasOwnProperty()
for (var i in man) {console.log(i, ":", man[i]);
}

另外一种使用hasOwnProperty()的形式是取消Object.prototype上的方法。像是:

for (var i in man) {if (Object.prototype.hasOwnProperty.call(man, i)) { // 过滤console.log(i, ":", man[i]);}
}

其好处在于在man对象重新定义hasOwnProperty情况下避免命名冲突。也避免了长属性查找对象的所有方法,你可以使用局部变量“缓存”它。

var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {if (hasOwn.call(man, i)) { // 过滤console.log(i, ":", man[i]);}
}

严格来说,不使用hasOwnProperty()并不是一个错误。根据任务以及你对代码的自信程度,你可以跳过它以提高些许的循环速度。但是当你对当前对象内容(和其原型链)不确定的时候,添加hasOwnProperty()更加保险些。

格式化的变化(通不过JSLint)会直接忽略掉花括号,把if语句放到同一行上。其优点在于循环语句读起来就像一个完整的想法(每个元素都有一个自己的属性”X”,使用”X”干点什么):

// 警告: 通不过JSLint检测
var i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) if (hasOwn.call(man, i)) { // 过滤console.log(i, ":", man[i]);
}

(不)扩展内置原型((Not) Augmenting Built-in Prototypes)

扩增构造函数的prototype属性是个很强大的增加功能的方法,但有时候它太强大了。

增加内置的构造函数原型(如Object(), Array(), 或Function())挺诱人的,但是这严重降低了可维护性,因为它让你的代码变得难以预测。使用你代码的其他开发人员很可能更期望使用内置的 JavaScript方法来持续不断地工作,而不是你另加的方法。

另外,属性添加到原型中,可能会导致不使用hasOwnProperty属性时在循环中显示出来,这会造成混乱。

因此,不增加内置原型是最好的。你可以指定一个规则,仅当下面的条件均满足时例外:

  • 可以预期将来的ECMAScript版本或是JavaScript实现将一直将此功能当作内置方法来实现。例如,你可以添加ECMAScript 5中描述的方法,一直到各个浏览器都迎头赶上。这种情况下,你只是提前定义了有用的方法。
  • 如果您检查您的自定义属性或方法已不存在——也许已经在代码的其他地方实现或已经是你支持的浏览器JavaScript引擎部分。
  • 你清楚地文档记录并和团队交流了变化。

如果这三个条件得到满足,你可以给原型进行自定义的添加,形式如下:

if (typeof Object.protoype.myMethod !== "function") {Object.protoype.myMethod = function () {// 实现...
   };
}

注释(Writing Comments)

你必须注释你的代码,即使不会有其他人向你一样接触它。通常,当你深入研究一个问题,你会很清楚的知道这个代码是干嘛用的,但是,当你一周之后再回来看的时候,想必也要耗掉不少脑细胞去搞明白到底怎么工作的。

很显然,注释不能走极端:每个单独变量或是单独一行。但是,你通常应该记录所有的函数,它们的参数和返回值,或是任何不寻常的技术和方法。要想到注 释可以给你代码未来的阅读者以诸多提示;阅读者需要的是(不要读太多的东西)仅注释和函数属性名来理解你的代码。例如,当你有五六行程序执行特定的任务, 如果你提供了一行代码目的以及为什么在这里的描述的话,阅读者就可以直接跳过这段细节。没有硬性规定注释代码比,代码的某些部分(如正则表达式)可能注释 要比代码多。

函数表达式和函数声明

在ECMAScript中,创建函数的最常用的两个方法是函数表达式和函数声明,两者期间的区别是有点晕,因为ECMA规范只明确了一点:函数声明必须带有标示符(Identifier)(就是大家常说的函数名称),而函数表达式则可以省略这个标示符:

  函数声明:

  function 函数名称 (参数:可选){ 函数体 }

  函数表达式:

  function 函数名称(可选)(参数:可选){ 函数体 }

所以,可以看出,如果不声明函数名称,它肯定是表达式,可如果声明了函数名称的话,如何判断是函数声明还是函数表达式呢?ECMAScript是通过上下文来区分的,如果function foo(){}是作为赋值表达式的一部分的话,那它就是一个函数表达式,如果function foo(){}被包含在一个函数体内,或者位于程序的最顶部的话,那它就是一个函数声明。

function foo(){} // 声明,因为它是程序的一部分var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分new function bar(){}; // 表达式,因为它是new表达式
(function(){function bar(){} // 声明,因为它是函数体的一部分})();

函数声明只能出现在程序函数体内。从句法上讲,它们 不能出现在Block(块)({ ... })中,例如不能出现在 if、while 或 for 语句中。因为 Block(块) 中只能包含Statement语句, 而不能包含函数声明这样的源元素。另一方面,仔细看一看规则也会发现,唯一可能让表达式出现在Block(块)中情形,就是让它作为表达式语句的一部分。但是,规范明确规定了表达式语句不能以关键字function开头。而这实际上就是说,函数表达式同样也不能出现在Statement语句或Block(块)中(因为Block(块)就是由Statement语句构成的)。

 

汤姆大叔博客笔记【随时更新】相关推荐

  1. 大叔手记(21):汤姆大叔博客园开博100天总结

    介绍 昨天是注册博客园的第100天,截止到今天大叔发了99篇帖子,加上今天这篇总共100篇,想来也应该来个总结了,本来是昨天写总结的,但由于加班,于是挪到今天了. 为何开博 博客这种事物在兴起的时候就 ...

  2. Javascript深入浅出理解----汤姆大叔博客(二)

    编写高质量JavaScript代码的基本要素 1)书写可维护代码 2)最小全局变量 JavaScript通过函数管理作用域.在函数内部声明的变量只在这个函数内部,函数外面不可用.另一方面,全局变量就是 ...

  3. 汤姆大叔JavaCript系列3阅读笔记

    Module模式: var blogModule = (function () {var my = {}, privateName = "博客园"; function privat ...

  4. 汤姆大叔JavaCript系列10阅读笔记

    原型对象也是普通的对象,并且也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链(prototype chain). ECMAScript没有类的概念.但是,重用[reus ...

  5. 汤姆大叔JavaCript系列10阅读笔记1

    闭包(Closures) 在ECMAScript中,函数是"第一类"对象.这个名词意味着函数可以作为参数被传递给其他函数使用 (在这种情况下,函数被称为"funargs& ...

  6. 为什么Android项目mainactivity中有一个变量R_博客笔记大汇总,Android优化总结篇

    博客笔记大汇总[16年3月到至今],包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并 ...

  7. Python表示不甘心,汤姆大叔送书,Python抢书之毫秒级跟进--获取服务器时间

    @鲜宏大牛果断使用js将抢书的误差提高到毫秒级, wid表示真心的很佩服鲜宏大牛! wid的水平虽说不怎么样, 但内心说, wid也想尝试着将抢书的误差提高到毫秒级, 思考了一会, 还真有思路了! 现 ...

  8. 收集优质的中文前端博客(不定期更新中)

    收集优质的中文前端博客(不定期更新中) 注:博主的公司信息来自网上公开资料,仅供参考,不保证准确性. 个人(控制在42个以内) 阮一峰的网络日志(蚂蚁金服) <读懂 ECMAScript 规格& ...

  9. 怎么禁止/开启Ubuntu自动更新升级_豆豆技术派的博客-CSDN博客_ubuntu 自动更新

    怎么禁止/开启Ubuntu自动更新升级_豆豆技术派的博客-CSDN博客_ubuntu 自动更新

最新文章

  1. poi设置单元格格式为文本_身份证号乱码?日期显示不对?都是单元格格式的锅...
  2. [脑海成像]科学家利用动态电极绕过眼睛直接刺激大脑,在盲人脑海画出字母
  3. 将 Shiro 作为应用的权限基础 五:密码的加密/解密在Spring中的应用
  4. STM8中GPIO的12种模式
  5. Solaris ALOM1.6 SC Password Reset
  6. 数据库:SQLServer 实现行转列、列转行用法笔记
  7. ASP.NET 数据库缓存依赖
  8. Java通过反射访问成员变量
  9. SpringBoot注解 @Configuration @PropertySource @ConfigurationProperties
  10. 如何为网站添加百度统计功能
  11. 【计算机组成原理】计算机的发展及应用
  12. 本地文件上传到阿里云生成网址
  13. k8s高可用环境部署7(Dashboard and metrics)
  14. 什么软件可以支持视频转换成文字?
  15. 适合于初学者—软路由全探索系列(一):探索 VMware 虚拟机旁路由安装及设置
  16. 阿里云域名注册详解与Github绑定
  17. 华为设备ACL配置命令
  18. 统信 UOS 连接 Windows 共享打印机
  19. 自行车改装电动车怎么样_电动车听起来应该是什么样?
  20. quartus编译报错:Error (176310): Can‘t place multiple pins assigned to pin location Pin_F16 (IOPAD_X34_Y1

热门文章

  1. 【2020年高被引学者】 杨强 香港科技大学
  2. live555交叉编译
  3. git 回滚远程分支
  4. java 对象数组与基本类型数组区别
  5. 关于withRouter的原理和用法
  6. 利用群晖的Webdav服务来使用流媒体平台Kodi
  7. META在2022年提出的最新创新
  8. Unity运用ASE(AmplifyShaderEditor)制作实时水倒影
  9. 用excel画简单曲线图的实践
  10. Java的JDBC编程