Rumah > Artikel > hujung hadapan web > Penjelasan terperinci tentang kemahiran JavaScript functions_javascript
Fungsi ialah satu set pernyataan yang boleh dijalankan pada bila-bila masa dan di mana-mana sahaja Fungsi adalah sangat penting sebagai teras ECMAScript. Fungsi ialah blok kod yang dipacu peristiwa atau boleh digunakan semula yang dilaksanakan apabila ia dipanggil. Iaitu, fungsi ialah sekeping kod JavaScript yang ditakrifkan sekali tetapi boleh dipanggil atau dilaksanakan beberapa kali. Fungsi kadangkala mempunyai parameter, iaitu pembolehubah tempatan dengan nilai yang ditetapkan apabila fungsi dipanggil. Fungsi sering menggunakan parameter ini untuk mengira nilai pulangan, yang juga menjadi nilai ungkapan panggilan fungsi.
1. Pengisytiharan fungsi
Fungsi ialah konsep teras untuk mana-mana bahasa. Sebarang bilangan pernyataan boleh dirangkumkan melalui fungsi, dan ia boleh dipanggil dan dilaksanakan di mana-mana dan pada bila-bila masa. Fungsi dalam JS diisytiharkan menggunakan kata kunci fungsi, diikuti dengan set parameter dan badan fungsi.
Sintaks asas fungsi adalah seperti berikut:
<span style="font-size:18px;">function functionName(arg0, arg1, ... argN) { statements }</span>
Terdapat tiga cara untuk mengisytiharkan fungsi yang ditentukan oleh ECMAScript:
(1) Pengisytiharan fungsi biasa
<span style="font-size:18px;">function box(num1,num2){ return num1+num2; }</span>
(2) Gunakan pemula pembolehubah atau pengisytiharan fungsi
<span style="font-size:18px;">var box=function(num1,num2){ return num1+num2; }</span>
(3) Gunakan pembina Fungsi untuk mengisytiharkan
function box(){ document.write("我是中国人!"); } box();//函数调用
Hasil pembedahan ialah: Saya Cina!
(2) Fungsi dengan parameter: Pembolehubah parameter ditakrifkan pada masa yang sama apabila fungsi diisytiharkan dan parameter boleh berbilang.
function box(name,age) { document.write("你的姓名是:"+name+"你的年龄是:"+age); } box("张三","24");//函数调用
Hasil operasi ialah: Nama anda: Zhang San
Umur anda ialah: 24
(3) Fungsi dengan nilai pulangan
Fungsi dengan dan tanpa parameter tidak mempunyai nilai pulangan yang ditentukan, tetapi dilaksanakan secara langsung selepas dipanggil. Malah, sebarang fungsi boleh merealisasikan nilai pulangan melalui pernyataan pulangan diikuti dengan nilai yang akan dikembalikan
1), fungsi tanpa parameter
function box(){ return "我是中国人!"; } document.write(box());
Keluaran yang sama seperti di atas: Saya orang Cina!
2), berfungsi dengan parameter
function box(name,age){ return "你的姓名是:"+name+"<br/>"+"你的年龄是:"+age; } document.write(box("张三","24"));//函数调用 document.write("<hr/>"); var demo=box("李四","23");//也可以重新赋值新的函数 document.write(demo);
Hasil larian ialah:
(4) Sebagai fungsi nilai (lebih istimewa)
Pertama, mari kita lihat contoh fungsi sebagai pembolehubah biasa:
function box(sum,num){ return sum+num;//这里传递的是函数的返回值和普通的变量一样 } function sum(num){ return num+10; } var result=box(sum(10),10); document.write("result="+result);
Hasil keluaran halaman ialah: hasil=30
Apa yang diluluskan di bawah adalah fungsi, bezakan dengan teliti daripada yang di atas:
function box(sum,num){ return sum(num);//这里传递的是函数 } function sum(num){ return num+10; } var result=box(sum,10); document.write("result="+result);
Hasil keluaran halaman ialah: hasil=20
3. Atribut dalaman fungsi
� Terdapat dua objek khas: objek argumen dan objek ini. Objek argumen ialah objek seperti tatasusunan yang mengandungi semua parameter yang dihantar ke dalam fungsi tersebut. Tetapi objek ini juga mempunyai atribut yang dipanggil callee, yang merupakan penunjuk kepada fungsi yang memiliki objek argumen.
(1)Atribut panjang bagi objek argumen
Fungsi JS tidak kisah berapa banyak parameter yang dihantar, dan tidak akan menyebabkan ralat disebabkan oleh parameter yang tidak konsisten. Malah, badan fungsi boleh diakses melalui objek argumen
Terima parameter yang diluluskan.
Mula-mula kita lihat masalah yang kita hadapi semasa menghantar parameter dalam fungsi: apabila fungsi diisytiharkan, kita tidak tahu berapa banyak parameter untuk ditakrifkan, tetapi apabila kita memanggil fungsi itu, terdapat terlalu banyak
masalah atau kekurangan.
function box(){ return arguments[0]+"|"+arguments[1]; } document.write(box(1,2,3,4,5,6));
输出的结果为: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 中非常强大多用的一部分,可用于执行复杂的计算。就像使用任何高级函数一样,使用闭包要小心,因为它们可能会变得非常复杂。
以上就是本文的全部内容,希望对大家的学习有所帮助。