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")表明脚本在执行时不会影响页面的构造,脚本会被延迟到 ...
随机推荐
- ios用storyboard快速创建静态cell
在实际开发中经常会遇到下面这样的页面,通常我们用静态cell来做可以快速创建,提高效率 下面讲一下用storyboard创建方法,将一个tableViewController控制器拖入storyboa ...
- Java 多线程 笔记 转自http://www.cnblogs.com/lwbqqyumidi/p/3804883.html
多线程作为Java中很重要的一个知识点, 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中 ...
- AnimatorController反向运动学IK
通过使用反向运动学IK,我们可以根据需要控制角色身体某个特定部位进行旋转或移动,达到想要的一些效果,比如:在移动时,让一只脚带伤拖行:让手抬起去拿桌上的苹果:让脑袋一直面向我们的色像机,就像一直注视着 ...
- 仿qq的条目抽屉动画效果_ViewDragHelper
GitHub地址: https://github.com/OOOOOldZhu/DrawerItemView import android.content.Context; import androi ...
- ActiveMQ in Action(7) - Wildcards
关键字: activemq 2.6.7 Wildcards Wildcards用来支持联合的名字分层体系(federated name hierarchies).它不是JMS规范的一部分,而是A ...
- GNU/Linux超级本ZaReason Ultralap 440体验
老早就在网上看到有关ZaReason公司推出了业界首款Linux超级本Ultralap 430的新闻.通过网上搜索,我了解到ZaReason是一家专门制作与销售预装Linux台式机.笔记本.超级本.平 ...
- iOS-OC对象模型
原文:http://blog.csdn.net/fanyiyao980404514/article/details/44864663 在C++的内存模型中我们知道,我们通过虚函数列表来存储虚函数的虚拟 ...
- struts2查询的数据的存放
当我们查询数据的时候,把它存放到一个位置.以供页面显示. 1:使用***Map取代内置对象存放 public String query(){ ActionContext.getContext().pu ...
- C#中使用like和in参数传值
like 参数string strSql = "select * from Person.Address where City like '%'+ @add + '%'";SqlP ...
- Design Pattern - Strategy
Strategy Pattern: The Strategy Pattern defines a family of algorithms,encapsulates each one,and ...