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")表明脚本在执行时不会影响页面的构造,脚本会被延迟到 ...
随机推荐
- SR-IOV简介
转载:http://docs.oracle.com/cd/E38902_01/html/E38873/glbzi.html SR-IOV 技术是一种基于硬件的虚拟化解决方案,可提高性能和可伸缩性.SR ...
- WebService一、数据交互
调用webservice总结: 1.加入第三方的jar包 Ksoap2-android-XXX 2.访问响应的webservice的网站,查看响应的信息,得到nameSpace,methodN ...
- getResourceAsStream和getResource的用法
用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大家最经常用的,就是用JAVA的File类,如要取得 D:/test.txt文件,就会这样用File file ...
- RubyMine 2016.1 下载 附注册激活码 破解版方法
注册破解方法: 在要求输入注册的界面选择激活码,然后粘贴以下注册码: 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIj ...
- JFrame
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class KeyDemo extends JFram ...
- PHP检测文件能否下载
用php代码检测一个文件是否可以下载,网上没有找到合适的代码,自己实现了一个还挺好用的,分享给有需要的朋友. 基本原理:使用http的HEAD方法,检测报文的头里httpcode是否为200. pub ...
- HDU 5904 LCIS
$dp$. 这题的突破口在于要求数字是连续的. 可以分别记录两个串以某个数字为结尾的最长上升长度,然后枚举一下以哪个数字为结尾就可以得到答案了. 因为$case$有点多,不能每次$memset$,额外 ...
- ubuntu16.04 禁用Guest用户
.打开终端(快捷键 Ctrl+Alt+T) .编辑50-no-guest.conf文件,按照以下命令编辑, sudo gedit /usr/share/lightdm/lightdm.conf.d/- ...
- Laravel默认使用utf8_unicode_ci 即使数据库是utf8_general_ci
这样做的后果是,不方便和utf8_general_ci字符串字段进行JOIN查询ON.
- 常用mysql命令
net start mysql命令,启动mysql数据库 1:查看服务器上存在哪些数据库:show databases;2:建立数据库mydb: create database mydb;3:使用你所 ...