6.函数
函数也是一个对象,可以想所有其他对象一样使用,唯一不同之处在于其可以被调用。
调用一个函数时,会暂停当前函数的运行,把控制权和参数传递给新函数,除了可见的定义时的参数,每个函数还会接收2个附加参数:this和arguments。
调用函数时,不会检查参数类型和个数,如果个数多了,自动忽略多余的,参数少了,补undefined。
方法的调用模式有4种: 方法调用模式,函数调用模式,构造器调用模式,apply调用模式。
方法调用模式:当函数是一个对象的属性时,被称作为对象的方法。以属性存取(‘.’,object[property])的方式调用.
var obj = {
value: 0,
increment: function(i) {
this.value += typeof(i) == 'number' ? i : 1;
return this.value;
}
};
alert(obj.increment());
alert(obj['increment']());
函数调用模式:当函数不是对象属性时,以函数方式调用,就是最常用的调用方式。但是需注意,使用这种调用模式时,this会被绑定到全局对象,导致的后果就是如果在对象内部使用函数调用方式将无法访问该对象的属性值,可通过提前把对象的this值保存起来,绕过该坑。
构造器调用模式:使用new前缀调用的函数被称为构造器函数,不推荐使用。
apply调用模式: 函数同样是对象,可以拥有方法,apply就是其中之一,apply方法有2个参数,第一个是this变量,第二个是参数组,以数组形式出现。
var add = function(v1,v2){
return v1 + v2;
};
var array = [3,4];
alert(add.apply(null,array)); //7
在函数调用时,会有一个附带的参数arguments,该参数是一个存储了调用函数时所有参数的对象。可以用来轻松实现一个变参的方法。
var add = function(){
alert(arguments.length);
var sum=0;
for (var i=0; i<arguments.length; i++){
sum +=arguments[i];
}
return sum;
};
alert(add(1,2,3,4)); //10
函数执行后,需要使用return语句指定返回值,未指定则返回undefined,在中间指定,则其后的所有语句直接跳过。
异常:throw抛异常对象,try-catch捕获异常,只会有一个捕获所有异常的catch模块,区分异常需要在异常处理模块自行解决。
可以为已知类型扩展方法,只需要向其prototype增加方法即可。和ruby的打开类技术一样。
Javascript有函数级作用域,但是无块级作用域,因此,最好在函数顶部声明函数中可能用到的所有变量。
使用回调函数处理不连续事件,可以防止因为调用的时延导致页面停滞.
使用模块模式摒弃全局变量的使用,缓解全局变量对系统的影响。所谓模块模式就是使用函数作用域和闭包来创建绑定对象与私有成员的关联,只以public方法的方式开放私有变量的访问。
使用级联,对于修改对象的状态但是不返回任何值的方法,我们可以返回this,从而可以级联的调用其它方法,这样可以让API更加的fluent,这样可以使代码更具表现力。
使用javascript做一些算法运算时,可以记住一些之前操作的结果,避免无谓的运算。例子,fibonacci函数:
var memorizer = function(memo, fundamental) {
var shell = function(n) {
var result = memo[n];
if (typeof result !== 'number'){
result = fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
var fibonacci = memorizer([0,1], function (shell,n)){
return shell(n-1) + shell(n-2);
});
7.继承
javascript中,对一个对象来说,重要的是它能做什么,而不是它从哪里来,但是继承作为一种重要的代码重用方式,同样得到支持。javascript实现继承的方式有几种:伪类。
伪类是通过定义constructor函数并替换掉它的prototype为一个其它类的实例实现。
对象说明符(Object Specifiers):其实就是当某个方法有多个参数时,最好能够打包传递,可以通过传递一个json对象给构造器,然后返回一个构造完全的对象。
使用Object.beget(my_obj)可以构造出my_obj的实例对象,然后可以定制该实例对象,以达到差异化继承的目的,
javascript中实现私有变量和方法的方式是函数化构造器,即在构造器中构建一个新的变量返回,在新构建的变量中添加方法,这些方法可以访问私有变量和方法。 外面则只能访问新构建变量提供的方法。