现在的位置: 首页 > 综合 > 正文

javascript函数

2018年05月04日 ⁄ 综合 ⁄ 共 5209字 ⁄ 字号 评论关闭

 http://blog.csdn.net/hzrui/archive/2009/03/03/3951289.aspx

   javascript函数

函数是指定义一次却可以调用多次或是运行多次的javascript代码段。要学好javascript,弄清楚函数是必要的。

学习函数必须要弄清楚以下几点:
 1. 声明方法
 2. 作用域
 3. 函数参数
 4. 函数调用

一. 声明

一般函数有三种声明方法,如下所示:

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
function f1(x,y)  
{  
    return x*y;  
}  
var f2 = function(x,y)  
{  
    return x*y;  
}  
var f3 = new Function("x", "y", "return x*y; ");  
// --></mce:script> 
<mce:script type="text/javascript"><!--
function f1(x,y)
{
 return x*y;
}
var f2 = function(x,y)
{
 return x*y;
}
var f3 = new Function("x", "y", "return x*y; ");
// --></mce:script>
 

前面两种应该是经常见到的,最后一种声明方式特殊一点,他接受n个参数(n>1),前n-1个参数是新函数的参数,最后一个参数是函数体。这种声明方式可以允许用户根据字符串动态创建一个函数,但每new Function一次就会动态编译并生成一个新的对象,如果调用了十次new Function,就生成了十个新的对象,如果放在经常调用的地方或是循环体内效率就低了。

二.函数的作用域

对于函数来说,他的作用域是在定义的时候就决定的,而不是在他调用的时候决定。但是用new Function声明的函数,他的作用域是全局,相当于是在全局定义的函数。关于具体的作用域知识,可以参考我之前写的文章:Javascript作用域浅析 。

三,函数的参数。

虽然函数声明时定义了参数列表,但这个参数列表其实只是提供了对应参数的一个快速引用而已。函数是可以用任意多的参数调用的。下面的函数f1跟注释掉的函数f1定义是一样的函数:

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
function f1(x,y)  
{  
    return x*y;  
}  
/* 
function f1() 

    x = arguments[0]; 
    y = arguments[1]; 
    return x*y; 

*/ 
// --></mce:script> 
<mce:script type="text/javascript"><!--
function f1(x,y)
{
 return x*y;
}
/*
function f1()
{
 x = arguments[0];
 y = arguments[1];
 return x*y;
}
*/
// --></mce:script>
 

在上面,我们看到了一个特殊的对象: arguments,注意,arguments并不是数组,它只是一个对象。arguments里面存贮了实际的调用参数,它和参数列表里面的参数是维护同一份数据的。下面的例子有助于理解。

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
function f1(x,y)  
{  
    arguments[0] = 1;  
    return x*y;  
}  
alert(f1(3,5)); //will display 5  
// --></mce:script> 
<mce:script type="text/javascript"><!--
function f1(x,y)
{
 arguments[0] = 1;
 return x*y;
}
alert(f1(3,5)); //will display 5
// --></mce:script>
 

上面的例子中,我们修改了arguments[0],同时参数列表里面的x的值也改变了。arguments还有两个属性,一个是length,指出参数的个数,还有一个属性callee,指向函数。下面我们用callee来计算阶乘:

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
var result = (function(x)  
{  
    if(x <=1) return 1;  
    return x* arguments.callee(x-1);  
})(3);     
alert(result);//will display 6  
// --></mce:script> 
<mce:script type="text/javascript"><!--
var result = (function(x)
{
 if(x <=1) return 1;
 return x* arguments.callee(x-1);
})(3);  
alert(result);//will display 6
// --></mce:script>
 

 

四.函数的调用

函数可以作为数据进行传递,但函数的作用域是在定义时候决定的,那么函数由谁调用有没有什么不同呢?答案是有的,差别就在于 this关键字。每个函数内部,都可以用this引用调用它的对象,读取或是修改对象的属性。所有没有声明调用对象的函数,默认都是由window调用,我们看看下面的例子:

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
var name= "window";  
var person = {  
    name : "person",  
    f1 : function()  
        {  
            return  this.name;  
        }  
}  
var f2 = person.f1;  
alert(f2());   //will display window  
alert(window.f2());  //will display window  
alert(person.f1());  //will display person  
alert( person.f1.call(window) ); //will display window  
alert( person.f1.call(person) ); //will display person  
alert( person.f1.apply(window) ); //will display window  
// --></mce:script> 
<mce:script type="text/javascript"><!--
var name= "window";
var person = {
 name : "person",
 f1 : function()
  {
   return  this.name;
  }
}
var f2 = person.f1;
alert(f2());   //will display window
alert(window.f2());  //will display window
alert(person.f1());  //will display person
alert( person.f1.call(window) ); //will display window
alert( person.f1.call(person) ); //will display person
alert( person.f1.apply(window) ); //will display window
// --></mce:script>
 

在上面,我们看到了this关键字指向的对象就是调用他的对象。其中,我们还看到了另外两种调用的方式:call, apply。这是函数的两个属性,可以用来调用函数,第一个参数都是指调用对象,而对于调用函数的参数,call是一个一个罗列,如 .call(obj, x, y),而apply是使用数组,如 .apply(obj, [x, y]) 。

到这里我们可以知道:

函数的作用域是定义时候确定的,是调用无关的。
函数是实现特定功能的代码段,由谁调用是定义无关的。比如A对象可以调用B对象内定义的方法。例如:我们可以用随便一个对象对用Array定义的方法。

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
var p = {  
    length : 0  
}  
Array.prototype.push.apply( p, [3, 4, 5] );  
alert(p.length); // will dispay 3  
alert(p[1]);    //will dispay 4  
// --></mce:script> 
<mce:script type="text/javascript"><!--
var p = {
 length : 0
}
Array.prototype.push.apply( p, [3, 4, 5] );
alert(p.length); // will dispay 3
alert(p[1]);    //will dispay 4
// --></mce:script>
 

最后,我们再来看看关于setTimeout()的调用。setTimeout函数是系统在window对象下直接初值化的一个函数,他并没有 call属性,所以只能用setTimeout()或是window. setTimeout()调用。它接受两个参数,第一个是运行的代码,它可以是字符串,也可以是一个函数。第二个参数是间隔时间,指多少时间后运行代码,以毫秒为单位。
如果第一个参数是字符串,javascript就会默认是javascriipt代码段,到时间后会在全局作用域下运行改javascript代码。就是说里面的作用域是全局,调用对象是 window。
如果第一个参数是函数,那么函数的作用域是已经定了的,不过调用对象是window。
我们看一下下面的例子。

view plaincopy to clipboardprint?
<mce:script type="text/javascript"><!--  
var name="window";  
var p = {  
    name: "obj",  
    fun : function(){  
        var name="local";  
        alert(this.name);  //if p call it ,will display obj  
        setTimeout("alert(name + ' and ' + this.name);", 1000); //all will display "window and windows"  
          
        setTimeout(function(){  
            alert(name);   //will display local  
            alert(this.name);   //will display window  
        }, 2000);  
    }  
}  
p.fun();  
// --></mce:script> 
<mce:script type="text/javascript"><!--
var name="window";
var p = {
 name: "obj",
 fun : function(){
  var name="local";
  alert(this.name);  //if p call it ,will display obj
  setTimeout("alert(name + ' and ' + this.name);", 1000); //all will display "window and windows"
  
  setTimeout(function(){
   alert(name);   //will display local
   alert(this.name);   //will display window
  }, 2000);
 }
}
p.fun();
// --></mce:script>
 

setInterval与setTimeout的区别在于setTimeout是只执行一次,而setInterval是间隔多少时间就执行一次,单是函数调用以及作用域的问题他们是一致的。

 

 

【上篇】
【下篇】

抱歉!评论已关闭.