JavaScript语言精粹(重读三)
接上篇函数返回
异常
try {
} catch(e) {
}
扩充类型的功能
有点像iOS中的分类
js允许给基本类型扩充功能。通过给Object的prototype添加方法,可以让该方法对所有对象起作用。这种方式可以给所有对象类型,比如函数、数组、字符串、数字。还有布尔值也适用。
Function.prototype.method = fucntion (name, func) {
this.prototype[name] = func;
return this;
}
这种方式一般用于一些添加一些公用的方法。
作用域
作用与控制着变量与参数的可见性及生命周期,减少了名称冲突以及提供自动内存管理。大多数语言和c一样有块级作用域。(在语句块一对花括号内,定义的所有变量在代码块外是不可见的,定义到在块中的变量会在代码块执行结束后释放掉)
但是在js中虽然语法貌似支持块级作用域,但是事实上是不支持的。js有函数作用域,意味着定义在函数中的参数对外部不可见,但是对函数内部任何地方都是可见的。
因为缺少块级作用域,所以做好的做法就是在函数体顶部声明所有可能用到的变量。
闭包
闭包就是能够读取其他函数内部变量的函数。
作用域的好处是可以访问定义在外部的变量(除了this和arguments)。
内部函数拥有比他外部函数更长的作用域
var myObject = (function (){
var value = 0;
return {
increment: function (inc) {
value += typeof inc === 'number' ?inc : 1;
},
getValue: funtion () {
return value;
}
};
}());
函数返回一个包含两个方法的对象,并且这些方法可以访问value。
注意:理解内部函数能访问外部函数的实际变量而无需复制是很重要
两大作用:
- 一个可以读取函数内部的变量,
- 另一个就是让这些变量的值始终保持在内存中。
这部分知识比较多
回调
常见场景就是异步请求网络中,为了防止假死状态。相关操作在异步回调中完成。
没有使用回调
request = prepare_the_request();
response = send_request_synchronously(request);
dispaly(response);
使用回调
send_request_asynchronously(request, function (response){
display(response);
});
模块
模块是一个提供接口但却隐藏了状态与实现的函数
或者对象
。可以通过函数或者闭包来构造模块。通过函数产生模块基本可以完全避免由于全局变量所带来的糟糕的影响。
在javascript
中,Module
模式用于进一步模拟类的概念,通过这种方式,可以使一个单独的对象拥有公有/私有方法和变量,从而屏蔽来自全局作用域的特殊部分。产生的结果是:函数名与在页面上其他脚本定义的函数冲突的可能性降低。
Module模式使用闭包封装”私有”状态和组织。它提供了一种包装混合公有/私有方法和变量的方式,防止其泄露至全局作用域,并与别的开发人员的接口发生冲突。通过该模式,只需返回一个公有API,而其他的一切都维持在私有闭包里面。
这样做为我们提供了一个屏蔽处理底层事件逻辑的整洁解决方案,同时只暴露一个接口供应用程序的其他部分使用。该模式除了返回一个对象而不是一个函数之外,非常类似于一个立即调用的函数表达式(IIFE
)。
级联
其实就是iOS中布局库mansory的使用方式。这种方式有个比价牛逼的名字函数式编程
原理就是调用一个方法,方法返回值是this。然后有个一继续调用另一个方法。形如:
getElement("MyBoxDiv")
.move(350, 150)
.width(100)
.height(100)
.padding("4px")
柯里化
名词有点不懂:
柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接收余下的参数而且返回结果的新函数的技术。
在js中函数也是值,柯里化允许把函数以及传递给函数的参数结合一下,产生一个新的函数。
var add1 = add.curry(1);
document.writeln(add1(6));// 7
记忆
函数可以将先前操作的结果记录子啊某个对象里面,从而避免无谓的重复运算。这种优化为记忆。js中的对象和数组要实现这种优化非常方便。
常见写法及时写一个对象保存在,在调用的时候先判断是否有值,如果有则跳过。
感觉这条并不是很有特别呀。为什么单独列出来。