Eine Funktion ist eine Reihe von Anweisungen, die jederzeit und überall ausgeführt werden können. Funktionen sind als Kern von ECMAScript sehr wichtig. Eine Funktion ist ein ereignisgesteuerter oder wiederverwendbarer Codeblock, der ausgeführt wird, wenn er aufgerufen wird. Das heißt, eine Funktion ist ein Stück JavaScript-Code, der einmal definiert wird, aber beliebig oft aufgerufen oder ausgeführt werden kann. Funktionen verfügen manchmal über Parameter, bei denen es sich um lokale Variablen handelt, deren Werte beim Aufruf der Funktion zugewiesen werden. Funktionen verwenden diese Parameter häufig zur Berechnung eines Rückgabewerts, der auch zum Wert des Funktionsaufrufausdrucks wird.
1. Funktionsdeklaration
Funktionen sind ein Kernkonzept für jede Sprache. Durch Funktionen können beliebig viele Anweisungen gekapselt werden, die überall und jederzeit aufgerufen und ausgeführt werden können. Funktionen in JS werden mit dem Schlüsselwort function deklariert, gefolgt von einer Reihe von Parametern und dem Funktionskörper.
Die grundlegende Syntax der Funktion lautet wie folgt:
<span style="font-size:18px;">function functionName(arg0, arg1, ... argN) { statements }</span>
Es gibt drei Möglichkeiten, von ECMAScript angegebene Funktionen zu deklarieren:
(1) Gewöhnliche Funktionsdeklaration
<span style="font-size:18px;">function box(num1,num2){ return num1+num2; }</span>
(2) Verwenden Sie die Variableninitialisierung oder Funktionsdeklaration
<span style="font-size:18px;">var box=function(num1,num2){ return num1+num2; }</span>
(3) Verwenden Sie den Funktionskonstruktor, um
zu deklarieren
function box(){ document.write("我是中国人!"); } box();//函数调用
(2) Funktion mit Parametern: Parametervariablen werden gleichzeitig definiert, wenn die Funktion deklariert wird, und die Parameter können mehrere sein.
function box(name,age) { document.write("你的姓名是:"+name+"你的年龄是:"+age); } box("张三","24");//函数调用
(3) Funktion mit Rückgabewert
Funktionen mit und ohne Parameter haben keinen definierten Rückgabewert, sondern werden direkt nach dem Aufruf ausgeführt. Tatsächlich kann jede Funktion den Rückgabewert durch die Return-Anweisung gefolgt von dem zurückzugebenden Wert realisieren
1), Funktion ohne Parameter
function box(){ return "我是中国人!"; } document.write(box());
2), Funktion mit Parametern
function box(name,age){ return "你的姓名是:"+name+"<br/>"+"你的年龄是:"+age; } document.write(box("张三","24"));//函数调用 document.write("<hr/>"); var demo=box("李四","23");//也可以重新赋值新的函数 document.write(demo);
(4) Als Funktion des Wertes (spezieller)
Schauen wir uns zunächst ein Beispiel einer Funktion als reguläre Variable an:
function box(sum,num){ return sum+num;//这里传递的是函数的返回值和普通的变量一样 } function sum(num){ return num+10; } var result=box(sum(10),10); document.write("result="+result);
function box(sum,num){ return sum(num);//这里传递的是函数 } function sum(num){ return num+10; } var result=box(sum,10); document.write("result="+result);
3. Interne Attribute von Funktionen
? Es gibt zwei spezielle Objekte: das Argumentobjekt und dieses Objekt. Das Argumentobjekt ist ein Array-ähnliches Objekt, das alle an die Funktion übergebenen Parameter enthält. Das Hauptattribut ist die Länge. Dieses Attribut wird verwendet, um dynamisch zu bestimmen, wie viele Parameter die Funktion hat. Aber dieses Objekt hat auch ein Attribut namens callee, das ein Zeiger auf die Funktion ist, die das Argumentobjekt besitzt.
(1)Das Längenattribut des Argumentobjekts
Der JS-Funktion ist es egal, wie viele Parameter übergeben werden, und sie verursacht keine Fehler aufgrund inkonsistenter Parameter. Tatsächlich kann auf den Funktionskörper über das Argumentobjekt zugegriffen werden
Empfangen Sie die übergebenen Parameter.
Schauen wir uns zunächst ein Problem an, das bei der Übergabe von Parametern in einer Funktion auftritt: Wenn die Funktion deklariert wird, wissen wir nicht, wie viele Parameter wir definieren müssen, aber wenn wir die Funktion aufrufen, sind es zu viele
Probleme oder Mängel.
输出的结果为:1|2。因此输出的显然与我们想要做的不符,那么怎么解决呢?
有了arguments对象的length属性我们就能可以得到参数的数量,避免上面的错误出现。
function box(){ return arguments.length; } document.write(box(1,2,3,4,5,6));
输出:6
我们还可以利用length属性来智能的判断有多少参数,然后把参数进行合理的应用,比如,实现一个加法运算,将所有传进来的数字累加,而数字的个数又不确定。
function box(){ var sum=0; if(arguments.length==0) { return sum; } for(var i=0;i<arguments.length;i++) { sum=sum+arguments[i]; } return sum;//返回累加结果 } document.write(box(1,2,3,4,5,6));
输出:21
(2)arguments对象的callee属性
还是来说问题:对于递归的问题我们很熟悉了,JS中也不例外
function box(num){ if(num<=1) { return 1; } else { return num*box(num-1);//递归 } } document.write(box(4));
输出:24
对于阶乘函数一般要用到递归算法,所以函数内部一定对调用自身,如果函数名不改变是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改。为了解决这个问题,可以使用arguments.callee来代替。
function box(num){ if(num<=1) { return 1; } else { return num*arguments.callee(num-1)//递归 } } document.write(box(4));
输出:24
(3)this对象
函数内部另一个特殊的对象时this,其行为与Java和C#中的this大致相似,换句话说,this引用的是函数据以行操作的对象,或者说函数调用语句所处的那个作用域。当在全局作用域中调用函数时,this对象引用的就是window(window是一个对象,是JavaScript中最大的对象,是最外围的对象)。
var color="红色";//这里的color是全局变量,并且这个变量是window的属性 document.write(window.color+"<br/>"); document.write(this.color+"<br/>"); var box={ color:"蓝色",//这里的color是box下的属性,是局部变量 sayColor:function(){ return this.color;//此时的this只能是box中的color } }; document.write(box.sayColor()+"<br/>");//局部的 document.write(this.color);//全局的
运行的结果为:
四、函数属性和方法
(1)JavaScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length和prototype。其中,length属性表示函数希望接受的命名参数的个数。
function box(num1,num2){ return num1+num2; } document.write(box.length);
输出的结果;2
对于prototype属性,它是保存所有实例方法的真正所在,也就是原型。这个属性我们先不做过多的介绍。prototype属性下有两个方法:apply()和call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
function box(num1,num2){ return num1+num2; } function sayBox(num1,num2){ return box.apply(this,[num1,num2]);//this表示作用域,这里是window,[]表示box所需的参数 } function sayBox2(num1,num2){ return box.apply(this,arguments);//arguments对象表示box所需的参数 } document.write(sayBox(10,10)+"<br/>"); document.write(sayBox2(10,10));
输出的结果为:20
20
(2)call()方法和apply()方法延伸
call()方法和apply()方法相同,它们的区别仅仅在于接收参数的方式不同。对于call()方法而言,第一个参数作用域,没有变化,变化的只是其余参数都是直接传递给函数的。
function box(num1,num2){ return num1+num2; } function callBox(num1,num2){ return box.call(this,num1,num2);//区别apply()方法 } document.write(callBox(10,10));
输出的结果为:20
call()方法和apply()方法真正的作用是扩展函数赖以运行的作用域
var color="红色";//全局变量 var box={ color:"蓝色",//局部变量 }; function sayColor(){ return this.color; } document.write(sayColor()+"<br/>");//作用域在Window document.write(sayColor.call(this)+"<br/>");//作用域在Window下 document.write(sayColor.call(window)+"<br/>");//作用域在Window下 document.write(sayColor.call(box));//作用域在box下,对象冒充
输出的结果为:
使用call()方法或者apply()方法来扩充作用域的最大好处就是对象不需要与方法发生任何耦合关系。也就是说,box对象和sayColor()方法之间不会有多余的关联操作,比如;box.sayColor=sayColor;
五、ECMAScript闭包
ECMAScrip最易让人误解的一点是,它支持闭包。闭包,指的是词法表示包括不被计算的变量的函数,就是说,函数可以使用函数之外定义的变量。
其实我在前面的博文已经使用到了闭包,比如在轻松学习JavaScript七:JavaScript的流程控制语句中使用的变量time就是全局变量,函数myFunction()使用这个全局变量,并不是函数本身定义的。还是看一下那个实例吧:
var time=new Date().getHours(); document.write("当前北京时间:"+time); function myFunction() { var x=""; if (time<20) { x="Good day"; } document.getElementById("demo").innerHTML=x; }
(1)简单的闭包实例
在ECMAScript中使用全局变量是一个简单的闭包实例。请思考下面这段代码输出的结果是什么:
var sMessage = "hello world"; function sayHelloWorld() { document.write(sMessage); } sayHelloWorld();
在上面这段代码中,脚本被载入内存后,并没有为函数sayHelloWorld()计算变量sMessage的值。该数捕 sMessage的值只是为了以后的使用,也就是说,解释程序知道在调用该函数时要检查sMessage的值。sMessage将在函数调用sayHelloWorld()是在(最后一行)被赋值,显示消息"hello world"。
(2)复杂的闭包实例
在一个函数中定义另一个会使闭包变得更加复杂。例如:
var iBaseNum = 10;//全局变量 function addNum(iNum1, iNum2) { function doAdd() { return iNum1 + iNum2 + iBaseNum; } return doAdd(); } document.write(addNum(10,10));
这里,函数addNum()包括函数doAdd()(闭包)。内部函数是一个闭包,因为它将获取外部函数的参iNum1和iNum2以及全局变量iBaseNum的值。 addNum()的最后一步调用了doAdd(),把两个参数和全局变量相加,并返回它们的和。这里要掌握的重要概念是,doAdd()函数根本不接受参数,它使用的值是从执行环境中获取的,因此输出的结果为:30。
可以看到,闭包是 ECMAScript 中非常强大多用的一部分,可用于执行复杂的计算。就像使用任何高级函数一样,使用闭包要小心,因为它们可能会变得非常复杂。
以上就是本文的全部内容,希望对大家的学习有所帮助。