Effective JavaScript :第二章
1.熟练掌握闭包
理解闭包要学会三个基本的事实:
①JavaScript允许你引用在当前函数以外定义的变量;
例如:
function makeSandwich(){
var magicIngredient = ‘peanut butter’;
function make(filling){
return magicIngredient + ‘and’ + filling;
}
return make(‘jelly’);
}
makeSandwich(); //‘peanut butter and jelly’
②即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量;
function sandwichMaker(){
var magicIngredient = ‘peanut butter’;
function make(filling){
return magicIngredient + ‘and’+filling;
}
return make;
}
var f = sandwichMaker();
f(‘jelly’);
f(‘bananas’);
f(‘marshmallows’);
f的值为内部的make函数,调用f实际上是调用make函数。
③闭包可以更新外部变量的值。
function box(){
var val = undefined;
return {
set : function(newVal){ val = newVal; },
get : function() { return val; },
type : function(){ return typeof val;}
};
}
val b = box();
b.type();
b.set(98.6);
b.get();
b.type();
该例子产生了一个包含三个闭包的对象,这三个闭包是set、get和type属性。它们共享访问val变量。set闭包更新val的值,随后调用get和type查看更新结果。
3.解决JavaScript缺少块级作用域的方法:
①创建一个嵌套函数并立即调用它来强制创建一个局部作用域:
function wrapElements(a){
var result = [];
for(var i = 0 , n = a.length; i < n ; i ++){
(function(){
var j = i;
result[i] = function(){ return a[j] ; };
})();
}
result result;
}
②将作为形参的局部变量绑定到IIFE并将其值作为实参传入。
使用IIFE来创建局部作用域要小心,因为在函数中包裹代码块可能会导致代码块发生一些微妙的变化。首先,代码块不能包含任何跳出块的break语句和continue语句。因为在函数外使用break和continue是不合法的。其次,如果代码块引用了this或特别的arguments变量,IIFE将会改变它们的含义。
4.匿名函数和命名函数表达式的官方区别在于后者会绑定到与其函数名相同的变量上,该变量将作为该函数内的一个局部变量。命名函数表达式的真正用处是进行调试。
5.在系统中,避免对象污染函数表达式作用域的最好方式是避免任何时候在Object.prototype中添加属性,以及避免任何使用与标准Object.prototype属性同名的局部变量。
6.命名函数表达式会导致很多问题所以不值得使用。
7.编写可移植函数的最好方式是始终避免将函数声明置于局部块或子语句中。如果想编写嵌套函数声明,应该将它置于其父函数的最外层,如果你需要有条件地选择函数,最好的办法就是使用var声明和函数表达式来实现。
function f(){ return ‘global’; }
function test(x){
var g = f , result = [];
if(x){
g = function(){ return‘local’; }
result.push(g());
}
result.push(g());
return result;
}
这消除了内部变量作用域的神秘性。它无条件地作为局部变量被绑定,而仅仅只有赋值语句是有条件地。结果很明确,该函数完全可移植。
8.错误使用eval的方式:
①允许它干扰作用域。
调用eval函数会将参数作为JavaScript程序进行解释。但是该程序运行于调用者的局部作用域中,嵌入到程序的全局变量会被创建为调用程序的局部变量。
function test(x){
eval(‘var y = x ;’ );
return y;
}
test(‘hello’); //‘hello’
保证eval函数不影响外部作用域的一个简单方法是在一个明确的嵌套作用域中运行它。
var y =‘global’;
function test(src){
(function () {eval(src);})();
return y;
}
test (“var y = ‘local’;”); //‘global’
test(“var z = ‘local’;”); //‘global’
9.间接调用eval函数优于直接调用
eval函数具有访问调用它那时的整个作用域的能力。
直接调用eval:
var x = ‘global’;
function test(){
var x = ‘local’;
return eval(‘x’);
}
test(); //‘local’;
间接调用eval:
var x = ‘global’;
function test(){
var x = ‘local’;
var f = eval ;
return f(‘x’) ;
}
test() ;
绑定eval函数到另一个变量名,通过该变量名调用函数会使代码失去对所有局部作用域的访问能力。
编写间接调用eval函数的一种简洁方式是使用表达式序列运算符(,)和一个明显毫无意义的数字字面量。
(0, eval)(src)
Effective JavaScript :第二章的更多相关文章
- JavaScript 数据访问(通译自High Performance Javascript 第二章) [转]
JavaScript 数据访问(通译自High Performance Javascript 第二章) JavaScript 数据访问(翻译自High Performance Javascript ...
- [Effective Java]第二章 创建和销毁对象
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 如何创建和销毁对象(Effective Java 第二章)
最近有在看Effective Java,特此记录下自己所体会到的东西,写篇博文会更加的加深印象,如有理解有误的地方,希望不吝赐教. 这章主题主要是介绍:何时以及如何创建对象,何时以及如何避免创建对象, ...
- 对于所有对象都通用方法的解读(Effective Java 第二章)
这篇博文主要介绍覆盖Object中的方法要注意的事项以及Comparable.compareTo()方法. 一.谨慎覆盖equals()方法 其实平时很少要用到覆盖equals方法的情况,没有什么特殊 ...
- 你不知道的JavaScript——第二章:this全面解析
1调用位置 调用栈:为了到达当前执行位置所调用的所有函数. function baz(){ //当前调用栈:baz //因此,当前调用位置是全局作用域 console.log('baz'); bar( ...
- JavaScript 第二章总结
Writing real code 设计程序的步骤 First, a high-level design and a flowchart more details Working through th ...
- javascript第二章--变量、作用域和内存问题
① 基本类型和引用类型的值 ② 执行环境及作用域 ③ 垃圾收集
- [Effective JavaScript 笔记]第3章:使用函数--个人总结
前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...
- Javascript权威指南——第二章词法结构,第三章类型、值和变量,第四章表达式和运算符,第五章语句
第二章 词法结构 一.HTML并不区分大小写(尽管XHTML区分大小写),而javascript区分大小写:在HTML中,这些标签和属性名可以使用大写也可以使用小写,而在javascript中必须小写 ...
- Javascript高级程序设计读书笔记(第二章)
第二章 在HTML中使用Javascript 2.1<script>元素 延迟脚本(defer = "defer")表明脚本在执行时不会影响页面的构造,脚本会被延迟到 ...
随机推荐
- hdu1039
#include<stdio.h>#include<string.h>const int MAXN=200;char str[MAXN]; bool isvowel(char ...
- Java基础知识之文件操作
流与文件的操作在编程中经常遇到,与C语言只有单一类型File*即可工作良好不同,Java拥有一个包含各种流类型的流家族,其数量超过60个!当然我们没必要去记住这60多个类或接口以及它们的层次结构,理解 ...
- volatile(C# 参考)
本文档已存档,并且将不进行维护. volatile(C# 参考) 若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 Visual Studio 2017 RC 文档. vo ...
- maven初步入门demo
Maven是跨平台的项目管理工具.作为Apache组织中的一个颇为成功的开源项目,主要服务于基于java平台的项目构建.依赖管理和项目信息管理. maven本身使用java开发而成,所以使用前确保电脑 ...
- B+树概念学习
转载自 从B树.B+树.B*树谈到R 树 1.用阶定义的B树 B 树又叫平衡多路查找树.一棵m阶的B 树 (注:切勿简单的认为一棵m阶的B树是m叉树,虽然存在四叉树,八叉树,KD树,及vp/R树/R* ...
- 记JavaScript的入门学习(二)
2016年11月25号,利用上午时间学习了JavaScript的数据类型和变量,下午就该去图书馆泡书了. 看完变量的本章节,发现我可能不能一天结束,那我就利用上午和晚上九点回来的时间完成吧.把心态调整 ...
- StringBuilder跟StringBuffer
一直以来只知道StringBuffer是线程安全的,StringBuilder是线程不安全的, 所以通常情况下使用StringBuilder,这样可以提升效率!!! 今天由于想起StringBuild ...
- 我喜欢的快捷键 webstorm
1.打开设置 ctrl+alt+s 2.重命名 rename ctrl+r
- 著名清理软件(CCleaner) 5.24.5841 中文版
软件名称: 著名清理软件(CCleaner) 软件语言: 多国语言 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 5.7MB 图片预览: 软件简介: CCleaner的体积小, ...
- Labeling Balls(变种拓扑)
Labeling Balls Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Tot ...