javascript中函数的全解简介

<script  language="javascript">
//切记特殊的两种函数声明方式
/*
//Function 构造
var f=new Function("x","document.write(x);");
 f(2);

 //函数直接量
 var g=function(y)
 {
 alert("I am the Function g().");
 }
 g();  
*/
function Rectangle_area(){return this.width*this.height;}
function Rectangle_perimeter(){return 2*(this.width+this.height);}
function Rectangle_set_size(w,h){this.width=w;this.heigh=h;}
function Rectangle_enlarge(){this.width*=2;this.height*=2;}
function Rectangle_shrink(){this.width/=2;this.height/=2;}
//初学javascript中的面向对象的编程方式
//构造Retangle对象定义一个构造函数方法
//构造函数不仅要初始化属性,还给方法赋值
function Rectangle(w,h)
{
 //初始化对象的属性
 this.width=w;
 this.height=h;
 //定义对象的方法
 this.area=Rectangle_area;
 this.perimeter=Rectangle_perimeter;
 this.set_size=Rectangle_set_size;
 this.enlarge=Rectangle_enlarge;
 this.shrink=Rectangle_shrink;
}
var r=new Rectangle(3,4);
var a=r.area();
r.enlarge();
var p=r.perimeter();
document.write("The rectangle's width is :"+r.width+"<br />This rectangle'height is :"+r.height);
//alert("The rectangle's area is :"+a+",The rectangle'perimeter is :"+p);


/*
自定义异常错误!
throw new Error("there is something wrong!");

*/

/*
直接函数的更多应用
直接函数和Function构造函数一样,函数直接两创建的是未命名函数,而且不会自动地将这个函数存储在
属性中。但是,比起Function函数构造创建的函数主体必须用一个字符串说明,用这种方式来表达一个长
而复杂的函数是很笨拙的。但是函数直接量的主体使用的却是标准的javascript语法。而且函数直接量植被
解析和编译一次,而作为字符串传递给Function构造函数的javascript代码则在每次调用构造函数时只需
被解析和编译一次。
*/

//作为数据的函数实例
function add(x,y){return  x+y;}
function subtract(x,y){return x-y;}
function multiply(x,y){return x*y;}
function divide(x,y){return x/y;}
//以下的函数可以将上面的某个函数作为参数
//他的两个参数是两个运算数。
function operate(operator,operand1,operand2)
{
 return operator(operand1,operand2);
}
//我们可以调用该函数
var i=operate(add,2,3);
document.write("<br />operate(add,2,3)的结果是:"+i);

//看到这里我不禁想到了c#中的委托代理
//这里就给了我们一个生动形象的实例来帮助我们理解委托代理
//C#中的委托代理的目的不就是为了将函数作为参数来传递
//在javascript中作为数据的函数,说白了就是为了实现我们在c#中的委托代理的目标.

var operators=new Object();
operators["add"]=function(x,y){return x+y;}
operators["subtract"]=function(x,y){return x-y;}
operators["multiply"]=function(x,y){return x*y;}
operators["devide"]=function(x,y){return x/y;}
operators["pow"]=Math.pow;

//以下的函数将运算符名作为参数,在数组中检索这个运算符.
//然后对运算数调用检索到的函数
//注意调用这个运算符函数的语法
function operate2(op_name,operand1,operand2)
{
 if (op_name==null)
 {
  return "unknown operator!";
 }
 else
 {
  return operators[op_name](operand1,operand2);
 }
}

//我们就可以使用以下的方式调用该函数计算值 ("hello"+" "+"world!")
//var j=opertate2("add","Hello",operate2("add"," ","world!"));
var k=operate2("add","Hello",operate2("add"," ","world!"));
document.write("<br >opertate2('add','Hello',operate2('add','','world!'))的结果是:"+k);
document.write("<br>operate2('pow'.10,2)的结果是:"+operate2("pow",10,2));
//个人意见
//这种使用方法实际上就是在javascript中提到的属性的关联数组的用法,为我们的编程提供了
//强大的灵活性.

//javascript函数的主体是在局部作用域中执行的,该作用域不同于全局作用域.这个新的作用域
//是通过调用对象添加到函数作用域链的头部创建的.因为调用对象是作用域链的一部分,所以
//在函数体内可以把这个调用对象的德属性作为变量来访问.用var语句声明的局部变量创建后
//作为调用对象的属性,而且函数的形式参数也可用于调用对象的属性.

/*
函数调用的实际参数:Arguments对象.
*/
function f(x,y,z)
{
 //首先检查传递参数的数量是否正确.
 if (arguments.length!=3)
 {
  throw new Error("Function f called with "+arguments.length+"arguments ,but it expects 3 arguments!");
 }
}
//f(1,2,6,6);

function max()
{
 var m=Number.NEGATIVE_INFINITY;
 //遍历所有参数,检索并保存其中最大的参数
 for (var i=0;i<arguments.length ;i++ )
 {
  if(arguments[i]>m) m=arguments[i];
  document.write("<br />arguments["+i+"]="+arguments[i]);
 }
 return m;
}

var largest=max(1,6,9,100,99,5);
document.write("<br />max(1,6,9,100,99,5)的结果是:"+largest);
/*
以上的实例中的Arguments对象很容易让我们认为它是一个数组,
但我要说明的一点就是这里的arguments不是一个数组而是一个对象,虽然它也有length属性
但我们如果把它看作偶然具有了一些带编码的属性的对象更合适些.
*/

//aruments对象还有callee属性
//用来引用当前正在执行的函数.看下面这个求阶乘的函数
var t=function(x)
{
 if(x<=1) return 1;
 return x*arguments.callee(x-1);
}
document.write("<br />5的阶乘是:"+t(5));


//函数的属性和方法
//知道了arguments数组的length属性指定了楚地为该函数的实际参数数目.但是函数自身的length属性的含义
//却非如此,它是只读的.返回的是函数需要的实际参数数目,也就是在函数的形式参数列表中声明的形式参数
//的数目.
function check(args)
{
 var actual=args.length;
 var expected=args.callee.length;
 if (actual!=expected)
 {
  throw new Error("Wrong number of arguments:expected : "+expected +";actually passed  "+actual);
 }
}

function f2(x,y,z)
{
 check(arguments);
 return f2.counter++;
}
//f2(4);
//同时函数还可以定义自己的属性
f2.counter=0
document.write("<br />第一次引用f2时的counter属性:"+f2(1,1,1)); //此时counter=2
document.write("<br />第二次引用f2时的counter属性:"+f2(1,1,1)); //此时counter=3
//document.write("<br />第三次引用f2时的counter属性:"+f2.counter);  //此时counter=3
//函数的apply()和call()方法
//call 和apply方法的第一个参数都是要调用的函数对象,在函数体内这一参数可以使用this的值,
//call()的剩余参数是传递给要调用的函数的值.
//apply()区别于call()的地方就是apply()的参数是用数组来传递的
var  d=new Array(1,2,3);
f2.call(f,1,2,3);                        //此时counter=4
document.write("<br />第三次引用f2时的counter属性:"+--f2.counter); 
f2.apply(this,d);                       //此时counter=2
document.write("<br />第四次引用f2时的counter属性:"+f2.counter);
f.call(f2,1,2,3);                        //此时counter=2,这里没有调用f2
document.write("<br />第五次引用f2时的counter属性:"+f2.counter);
//以上现象比较怪异,应该多想想!
//实际上以上主要在让我熟悉++的运算
</script> 

原文地址:https://www.cnblogs.com/itelite/p/1036119.html