javascript API模式:
可以帮助我们为函数提供更好,更整洁的接口。这些模式主要包括以下几个:
1)回调模式:
函数也是对象,因此可以作为参数传递,看如下例子:
function demo01 (callback){
callback();
}
function test01(){
console.log("aaa");
}
demo01(test01);//"aaa"
下面来看看回调及其作用域:
var myobj = {
name:"zhangsan",
setName:function(person){
person.name = this.name;
}
};
function getName(callback){
var obj={};
if(typeof callback === "function"){
callback(obj);
}
return obj.name;
}
console.log(getName(myobj.setName));//返回空字符,因为此时的this 引用的是全局对象(window),window.name并么有定义。
怎么解决这个问题呢?使用回调并传递回调所属的对象。
var myobj = {
name:"zhangsan",
setName:function(person){
person.name = this.name;
}
};
function getName(callback,callObj){
var obj={};
if(typeof callback === "string"){
callback = callObj[callback];
}
if(typeof callback === "function"){
callback.call(callObj,obj);
}
return obj.name;
}
console.log(getName("setName",myobj));//zhangsan
console.log(getName(myobj.setName,myobj));//zhangsan
2)配置对象模式:
优点:
a)不需要记住很多参数,及其顺序;
b)可以安全忽略可选参数
c)易于阅读和维护
d)易于添加和删除参数
缺点:
a)使用时需要记住参数名称
b)进行代码优化及压缩时,属性名称无法压缩
var configure = {
name:"zhangsan",
sex :"male",
age :23
}
setPerson(configure);//进行参数传递
3)返回函数模式:
函数是对象,因此可以做为返回值返回。看下面的函数:
var parent = function(){
var name = "zhangsan";
return function(){
return name;
}
}
console.log(parent()());//zhangsan
parent()函数返回了一个函数,创建了一个闭包,我们可以使用这个闭包存储一些私有数据,而这些数据仅可
被返回函数访问,但是外部代码却不可访问。下面我们来看一个计数器的例子:
var getCount = function(){
var i=0;
return function(){
return ++i;
}
}
var getI = getCount();
getI();//1
getI();//2
getI();//3
4)Curry化模式:
我们先来做一个加法的例子:
var add = function(x,y){
return x+y;
}
add(1,2)//3
现在把单步运行模拟如下:
var add = function(x,y){
return 1+y;
}
var add = function(x,y){
return 1+2;
}
我们来curry化add函数以达到我们想要的要求:
var add = function(x,y){
if(typeof y === "undefined"){
return function(y){
return x + y;
}
}
return x+y;
}
console.log(add(1));//function
console.log(add(1,2));//3
console.log(add(1)(2));//3
根据以上实例,我们来封装一个curry化函数myCurry
function myCurry(fn){
var slice = Array.prototype.slice,
oldargs = slice.call(arguments,1);
return function(){
var newargs = slice.call(arguments),
args = oldargs.concat(newargs);
return fn.apply(null,args);
}
}
function multi(a,b,c,d){
return a*b*c*d;
}
console.log(myCurry(multi,1,2)(3,4));//24
根据以上实例,那么我们何时使用Curry化呢,当我们发现调用同一个函数,并且传递的参数绝大多数都是相同的时候,可以考虑使用函数Curry化。