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")表明脚本在执行时不会影响页面的构造,脚本会被延迟到 ...
随机推荐
- 果园种植系统开发App,游戏+商业模式?
果园种植全返系统开发,英伦果园开发,微信果园种植系统开发,百果生态乐园开发,淘金农夫开发,农场果园种植游戏系统,果园种植APP系统开发,果园种植软件开发找陈牧150-1315-1740(微/电)开发者 ...
- SQL性能优化注意事项
1.选用适合的Oracle优化器 Oracle的优化器共有3种: a.RULE(基于规则) b.COST(基于成本) c.CHOOSE(选择性) 设置缺省的优化器,可以通过对init.ora文件中OP ...
- CSS3效果收集
收集一些 CSS3 效果 1. 闪烁字效果 原效果>>
- 使用Gradle编译release apk报错:Please correct the above warnings first
在开发SDK的过程中,遇到了一个研发,使用了自己的SDK之后遇到了各种问题,于是我们自己帮忙接入. 所有代码都接入完成之后,准备export出一个release包,但是此时却报错: 此时出现了很多的w ...
- 曾经让我很吐血的Bug(初学者)
1.MSSql 就是 sql Server. 2.用session的时候一定要先实现接口IRequiresSessionState: 3.form表单中type=file传送文件的时候一定要在form ...
- Redis安装(CentOS7/tar.gz)
1. 将安装包redis-3.2.0.tar.gz上传到linux系统,位置随意. 2. 解压文件 .tar.gz 3. 解压后会在当前目录生成文件夹“redis-3.2.0”,将其拷贝到" ...
- Vue.js教程
https://aotu.io/notes/2016/10/13/vue2/?o2src=juejin&o2layout=compat
- centos安装ganttproject
官网下载 http://www.ganttproject.biz/ 我的JAVA早已经安装了. 问题:root #ganttproject 提示org.bardsoftware.eclipsito.B ...
- Unity 解决 An asset is marked with HideFlags.DontSave but is included in the build 问题。
问题是:不能使用Unity使用的默认的字体.想要显示中文直接去下载一个字体.没必要使用默认的字体
- Linq 内联左联等
我们在做SQL查询的时候经常会用到Inner Join,Left Join,笛卡尔积等等,连接方式的概念方面我想也不用给予太多解释, 我们今天的重点是让大家熟悉LINQ是如何使用Join来实现常用的表 ...