JS语言精粹之函数

来源:互联网 发布:ubuntu软件中心下载 编辑:程序博客网 时间:2024/05/21 08:35
创建函数的几种方式
1声明函数
最普通最标准的声明函数方法包括函数名及函数体
function fn1(){}

2创建匿名函数表达式
创建一个变量这个变量的内容为一个函数
var fn1=function (){}
注意采用这种方法创建的函数为匿名函数即没有函数name
var fn1=function (){};
getFunctionName(fn1).length;//0

3创建具名函数表达式
创建一个变量内容为一个带有名称的函数
var fn1=function xxcanghai(){};
注意具名函数表达式的函数名只能在创建函数内部使用
即采用此种方法创建的函数在函数外层只能使用fn1不能使用xxcanghai的函数名xxcanghai的命名只能在创建的函数内部使用
测试
var fn1=function xxcanghai(){
console.log("in:fn1typeof fn1,">xxcanghai:typeofxxcanghai,">");
};
console.log("out:fn1typeof fn1,">xxcanghai:typeofxxcanghai,">");
fn1();
//out:fn1xxcanghai:undefined >
//in:fn1xxcanghai:
可以看到在函数外部out无法使用xxcanghai的函数名为undefined
注意在对象内定义函数如varo={ fn : function (){…} },也属于函数表达式

4Function构造函数
可以给 Function 构造函数传一个函数字符串返回包含这个字符串命令的函数此种方法创建的是匿名函数

5自执行函数
(function(){alert(1);})();
(function fn1(){alert(1);})();
自执行函数属于上述的函数表达式”,规则相同
----------------------------------------------------------------------------------------------
函数调用:方法调用模式、函数调用模式、构造器调用模式、apply调用模式
方法调用模式:当一个函数被保存为对象的一个属性时,我们称它是一个方法,当一个方法被调用的时候,this被绑定
到该对象。
var myObject={
value:0,
increment:function(inc){
this.value +=typeofinc ==='number'?inc:1;
}
};
myObject.increment(2);
document.write(myObject.value);//2
函数调用模式:当一个函数并非一个对象的属性的时候,那么他就是当做一个函数来调用的:
var sum=add(3,4);
此模式调用函数时候,this被绑定到全局对象。这是语言设计的一个错误,假如语言设计正确,当内部函数被调用时,
this应该绑定到外部函数的this变量,解决方案 that
var myObject = {
value: 4,
increment: function (inc) {
this.value +=typeof inc ==='number' ? inc :1;
}
};
function add(a,b){
return a+b;
};

//给myObject添加一个double方法
myObject.double =function () {
var that =this;
var helper =function () {
that.value =add(that.value,that.value);
};
helper();//以函数形式调用helper
};
//以方法形式调用double
myObject.double();
console.log(myObject.value);//8

构造器调用模式:new
var Guo=function(string){
this.status=string;
};
Guo.prototype.get_status=function(){
return this.status;
};
var guo=newGuo('SMART');
console.log(guo.get_status());
apply调用模式:接受两个参数,第一个参数是要绑定的this的值,第二个是参数数组
var Guo=function(string){
this.status=string;
};
Guo.prototype.get_status=function(){
return this.status;
};
var statusObject={
status:'guanguan'
};
//statusObject并没有继承自Guo.prototype,但我们可以在status上调用get_status方法
var status=Guo.prototype.get_status.apply(statusObject);
console.log(status);//guanguan
-------------------------------------------------------------------------------------------------
函数递归
-------------------------------------------------------------------------------------------------
函数作用域
------------------------------------------------------------------------------------------------
闭包:
var myObject=(function(){
var value=0;
return {
increment:function(inc){value +=typeofinc === 'number' ?inc : 1;},
getValue:function(){returnvalue}
};
}());
我们并没有把一个函数值给myObject,我们把调用函数后返回的结果复制给它,注意最后一行的(),该函数包含两个方法的
对象,并且这些方法继续享有访问value变量的特权。但是value对于其他的程序是不可见的。
var guo=function(status){
return {
get_status:function(){
return status;
}
};
};//创建一个构造函数 guo,返回带有get_status方法和status属性的一个对象
var myguo= guo('guanguan');//构造一个guo实例
console.log(myguo.get_status());
--------------------------------------------------------------------------------------------------------
模块:使用函数和闭包来构造模块,模块可以摒弃全局变量的使用,一般形式:一个定义了私有变量和函数的函数;
利用闭包创建可以访问私有变量和函数的特权函数;最后返回这个特权函数,或者把它们保存到可以访问到的地方。
String.method('deentityify',function(){
var entity={
quot:'"',
lt:'<',
gt:'>'
};
return function (){
return this.replace(/&([^&;]+));/g,
function(a,b){
var r=entity[b];
return typeof r==='string'?r:a;
}
);
};
}());
console.log('&lt;&quot;&gt;'.deentityify());

模块也可以用来产生安全的对象:

var serial_maker=function(){
var prefix='';
var seq=0;
return {
set_prefix:function(p){
prefix=String(p);
},
set_seq:function(s){
seq=s;
},
gensym:function(){
var result = prefix+seq;
seq += 1;
return result;
}
};
};
var seqer = serial_maker();
seqer.set_prefix('q');
seqer.set_seq(10000);
var unique=seqer.gensym();
console.log(unique);//q10000
-----------------------------------------------------------------------------------------------------
函数柯里化:函数也是值,柯里化允许我们把函数与传递给它的参数相结合,产生一个新的函数。
function add(a,b){
return a+b;
};
function curry(b){
return add(8,b);
};
var add1=curry(1);
console.log(add1);//9

//curry()函数的主要工作就是将被返回的函数的参数进行排序,curry第一个参数是要柯里化的函数
第二个参数是要传入的值。
function curry(fn){
var args=Array.prototype.slice.call(arguments,1);//获取第一个参数之后的所有参数,传入参数1表示被返回的数组包含
从第二个参数开始的所有参数,args包含了来自外部函数的参数。
return function(){
var inner=Array.prototype.slice.call(arguments);//用来存放所有传入的参数。
var final=args.concat(inner);//
return fn.apply(null,final);
};
};

function add(a,b){
return a+b;
};
var curry1=curry(add,5);
console.log(curry1(3));//8













原创粉丝点击