详解J**aScript函数

时间:2016.04.18 发布人:yangjh1201

详解J**aScript函数

已解决问题

谷歌yangjh1201用户在2016.04.18提交了关于“吴昕详解J**aScript函数”的提问,欢迎大家涌跃发表自己的观点。目前共有1个回答,最后更新于2025-03-03T23:24:45。希望大家能够帮助她。

详细问题描述及疑问:期待您的答案,当代劳模,所有人都应该向你学习 !

希望以下的回答,能够帮助你。

第1个回答

用户名:猫猫向前冲啊  

振论数是一组可以随时随地运行的语句问答,函数作为ECMAScript的核心是很重要的。函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。也就是函数是定义一次但却可以调用或执行任意多次的一段JavaScript且氧觉垂事初代码。函数有时会有参数,即函数被调用时指定了值的局部变量。函数常常使用这些参数来计算一个返回值,这个值也成为函数调用表达式的值。
一、函数今占争声明
函数对于任何语言来思是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方,任何时候调跟即判女阿持度用执行。JS中的函数使用f沉执更油设自热抗务境unction关键字来声明把意华依个套构脱另律,后跟一组参数以及函数体。
函数的基本语法是这样的:

<spanstyle="font-size:18px;">functionf皇当陈三找导良响unctionName(arg0,arg1,argN){state刻弦温病持互织内终ments}</span>

ECMAScript规定的函数声明方式有三种:
(1)普通函数声明

<spanst后操你溶坐yle="font-size:18px;">functionbox(**m1,**m2){return**m1+**m2;}</span>

(2)使用变量初始化什声明函数

<spanstyle="font-size:18px;">v长队首令争渐张arbox=function(**m1,**m2){return**m1+**m2;}</span>

(氧3)使用Function构造然类国次说函数声明
复制代码代码如引系先下:<spanst识由亚yle="font-size:18px;">vaxbox=newFunction('**m1','**m2','**m1+**m2');</span>
二、函数的类型及函数的调用
ECMAScript语法规定了
(1)无参数的函数:函数的声明的时候没有参数,调用函数的时候直唱战声搞谈甲林久接使用即可。

functionbox(){document.write("我是中聚你铁执晚孩入国人!");}box();//函数调用

运行的结果为:我是中国人!
(2)带参数的函数:函数的声明的时候同时定义了参数变量,参数可以是多个。

functionbox(nam岁征套财e,age){document.write("你的姓名是:"+name+"你的年龄是:"+age);}box("张三","24");//函数调用

运行的结果为:你的姓名是:张三
你的年龄是:24
(3)带有返回值的函数
带参数和无参数的函数,都没有定义返回值,而是调用后直接执行的,实际上,任何函数都可以通过return语句系优状信跟后面的要返回的值来实现返回值
1)、无参数的函数

functionbox(){return"我是中国人!";}document.write(box());

同上面的输出结果:我是中国人!
2)、带参数的函数

functionbox(name,age){return"你的姓名是:"+name+"<br/>"+"你的年龄是:"+age;}document.write(box("张三","24"));//函数调用document.write("<hr/>");vardemo=box("李四","23");//也可以重新赋值新的函数document.write(demo);

运行的结果为:

(4)作为值的函数(比较特殊)
首先我们来看一个函数作为常规的变量的例子:

functionbox(sum,**m){returnsum+**m;//这里传递的是函数的返回值和普通的变量一样}functionsum(**m){return**m+10;}varresult=box(sum(10),10);document.write("result="+result);

页面的输出结果为:result=30
下面则传递的是函数,仔细和上面的区分:

functionbox(sum,**m){returnsum(**m);//这里传递的是函数}functionsum(**m){return**m+10;}varresult=box(sum,10);document.write("result="+result);

页面的输出结果为:result=20
三、函数的**属性
在函数**,有两个特殊的对象:arguments对象和this对象。arguments对象是类数组对象,包含着传入函数中的所有参数,主要用途是保存函数参数,主要的属性有length,这个属性是动态的判断函数有多少个参数。但这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
(1)arguments对象的length属性
JS函数不介意传递进来多少参数,也不会因为参数不统一而错误。实际上,函数体内可以通过arguments对象来
接收传递进来的参数。
我们先来看一个我们在函数传递参数遇到的问题:函数声明时并不知道要定义多少个参数,在调用函数却出现多
出的或不足的问题。

functionbox(){returnarguments[0]+"|"+arguments[1];}document.write(box(1,2,3,4,5,6));

输出的结果为:1|2。因此输出的显然与我们想要做的不符,那么怎么解决呢?
有了arguments对象的length属性我们就能可以得到参数的数量,避免上面的错误出现。

functionbox(){returnarguments.length;}document.write(box(1,2,3,4,5,6));

输出:6
我们还可以利用length属性来智能的判断有多少参数,然后把参数进行合理的应用,比如,实现一个加法运算,将所有传进来的数字累加,而数字的个数又不确定。

functionbox(){varsum=0;if(arguments.length==0){returnsum;}for(vari=0;i<arguments.length;i++){sum=sum+arguments[i];}returnsum;//返回累加结果}document.write(box(1,2,3,4,5,6));

输出:21
(2)arguments对象的callee属性
还是来说问题:对于递归的问题我们很熟悉了,JS中也不例外

functionbox(**m){if(**m<=1){return1;}else{return**m*box(**m-1);//递归}}document.write(box(4));

输出:24
对于阶乘函数一般要用到递归算法,所以函数**一定对调用自身,如果函数名不改变是没有问题的,但一旦改变函数名,**的自身调用需要逐一修改。为了解决这个问题,可以使用arguments.callee来代替。

functionbox(**m){if(**m<=1){return1;}else{return**m*arguments.callee(**m-1)//递归}}document.write(box(4));

输出:24
(3)this对象
函数**另一个特殊的对象时this,其行为与J**a和C#中的this大致相似,换句话说,this引用的是函**以行操作的对象,或者说函数调用语句所处的那个作用域。当在全局作用域中调用函数时,this对象引用的就是window(window是一个对象,是J**aScript中最大的对象,是最**的对象)。

varcolor="红色";//这里的color是全局变量,并且这个变量是window的属性document.write(window.color+"<br/>");document.write(this.color+"<br/>");varbox={color:"蓝色",//这里的color是box下的属性,是局部变量sayColor:function(){returnthis.color;//此时的this只能是box中的color}};document.write(box.sayColor()+"<br/>");//局部的document.write(this.color);//全局的

运行的结果为:

四、函数属性和方法
(1)J**aScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length和prototype。其中,length属性表示函数希望接受的命名参数的个数。

functionbox(**m1,**m2){return**m1+**m2;}document.write(box.length);

输出的结果;2
对于prototype属性,它是保存所有实例方法的真正所在,也就是原型。这个属性我们先不做过多的介绍。prototype属性下有两个方法:apply()和call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。

functionbox(**m1,**m2){return**m1+**m2;}functionsayBox(**m1,**m2){returnbox.apply(this,[**m1,**m2]);//this表示作用域,这里是window,[]表示box所需的参数}functionsayBox2(**m1,**m2){returnbox.apply(this,arguments);//arguments对象表示box所需的参数}document.write(sayBox(10,10)+"<br/>");document.write(sayBox2(10,10));

输出的结果为:20
20
(2)call()方法和apply()方法延伸
call()方法和apply()方法相同,它们的区别仅仅在于接收参数的方式不同。对于call()方法而言,第一个参数作用域,没有变化,变化的只是其余参数都是直接传递给函数的。

functionbox(**m1,**m2){return**m1+**m2;}functioncallBox(**m1,**m2){return***.call(this,**m1,**m2);//区别apply()方法}document.write(callBox(10,10));

输出的结果为:20
call()方法和apply()方法真正的作用是扩展函数赖以运行的作用域

varcolor="红色";//全局变量varbox={color:"蓝色",//局部变量};functionsayColor(){returnthis.color;}document.write(sayColor()+"<br/>");//作用域在Windowdocument.write(***.call(this)+"<br/>");//作用域在Window下document.write(***.call(window)+"<br/>");//作用域在Window下document.write(***.call(box));//作用域在box下,对象冒充

输出的结果为:

使用call()方法或者apply()方法来扩充作用域的最大好处就是对象不需要与方法发生任何耦合关系。也就是说,box对象和sayColor()方法之间不会有多余的关联操作,比如;box.sayColor=sayColor;
五、ECMAScript闭包
ECMAScrip最易让人误解的一点是,它支持闭包。闭包,指的是词法表示包括不被计算的变量的函数,就是说,函数可以使用函数之外定义的变量。
其实我在前面的博文已经使用到了闭包,比如在轻松学习J**aScript坪J**aScript的流程控制语句中使用的变量time就是全局变量,函数myFunction()使用这个全局变量,并不是函数本身定义的。还是看一下那个实例吧:

vartime=newDate().geth**ours();document.write("当前北京时间:"+time);functionmyFunction(){varx="";if(time<20){x="Goodday";}document.getElementById("demo").innerh**TML=x;}

(1)简单的闭包实例
在ECMAScript中使用全局变量是一个简单的闭包实例。请思考下面这段代码输出的结果是什么:

varsMessage="helloworld";functionsayh**elloWorld(){document.write(sMessage);}sayh**elloWorld();

在上面这段代码中,脚本被载入内存后,并没有为函数sayh**elloWorld()计算变量sMessage的值。该数捕sMessage的值只是为了以后的使用,也就是说,解释程序知道在调用该函数湿检查sMessage的值。sMessage将在函数调用sayh**elloWorld()是在(最后一行)被赋值,显示消息"helloworld"。
(2)复杂的闭包实例
在一个函数中定义另一个会使闭包变得更加复杂。例如:

variBaseNum=10;//全局变量functionaddNum(iNum1,iNum2){functiondoAdd(){returniNum1+iNum2+iBaseNum;}returndoAdd();}document.write(addNum(10,10));

这里,函数addNum()包括函数doAdd()(闭包)。**函数是一个闭包,因为它将获取外部函数的参iNum1和iNum2以及全局变量iBaseNum的值。addNum()的最后一步调用了doAdd(),把两个参数和全局变量相加,并返回它们的和。这里要掌握的重要概念是,doAdd()函数根本不接受参数,它使用的值是从执行环境中获取的,因此输出的结果为:30。
可以看到,闭包是ECMAScript中非常强大多用的一部分,可用于执行复杂的计算。就像使用任何高级函数一样,使用闭包要小心,因为它们可能会变得非常复杂。

以上就是本文的全部内容,希望对大家的学习有所帮助。