Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
通俗的來講,函數(shù)是由事件驅(qū)動的或者當它被調(diào)用時執(zhí)行的可重復使用的代碼快。它是 JavaScript 語言一個即重要又復雜的組成部分,任何一個 JavaScript 框架,如 Dojo、jQuery 等都是有成百上千個函數(shù)組成的。函數(shù)的使用不僅提高了代碼本身的可讀性,也為它的擴展提供了可能,同時還降低了維護成本,加快 web 項目的開放進度;尤其是在多人參與的敏捷開發(fā)中。
通常函數(shù)的定義是通過 function 語句實現(xiàn)的:
清單 1.函數(shù)定義
funcname 是要定義的函數(shù)名,是一個標識符,而不是字符串或者表達式;緊跟函數(shù)名后面的是用括號括起來的參數(shù)列表,參數(shù)之間用逗號隔開;最后,也是這個函數(shù)的核心部分:函數(shù)體,它是由一行或者多行代碼組成并且是用大括號括起來的。
函數(shù)定義描述的是一個靜態(tài)的程序結(jié)構(gòu),當 JavaScript 解析器遇到一個函數(shù)定義時,它就被解析并存儲構(gòu)成函數(shù)體的語句,然后定義一個和該函數(shù)名同名的全局或者某個對象屬性來保存。當該函數(shù)被調(diào)用時,里面的函數(shù)體才真正的被執(zhí)行。如:
清單 2
定義一個函數(shù),最為普遍的是直接使用 function 關(guān)鍵字來定義,又稱函數(shù)聲明式(function declaration),如上面定義的 f 函數(shù),但是 function 語句并非是定義函數(shù)的惟一方法。在 ECMAScript v1 和 JavaScript v1.1 中,還可以使用 Function () 構(gòu)造函數(shù)和 new 運算符動態(tài)地定義函數(shù),如下:
var myfunc=new Function ('x', 'y', 'alert(x+y)');
這行代碼創(chuàng)建了一個新函數(shù),該函數(shù)和下面使用 function 方法定義的函數(shù)是等價的:
清單 3.
Function () 定義中,前面兩個是參數(shù),參數(shù)可以是任意多個字符串;第三個是函數(shù)體,可以包含任何 JavaScript 語句,語句之間用分號隔開。如果沒有參數(shù),傳一個函數(shù)體即可。由于傳遞給 Function () 函數(shù)中,沒有一個字符串是用來聲明函數(shù)名的,所以它是一個匿名函數(shù)。
使用 Function()構(gòu)造函數(shù)來定義函數(shù)允許我們動態(tài)的來定義和編譯一個函數(shù),而不是限定在 function 預編譯的函數(shù)體中。但同時也會帶來負面影響,因為每次調(diào)用這個函數(shù)都要對它進行編譯,對性能有一定的影響,尤其是在循環(huán)體中。
函數(shù)定義的第三種方式是函數(shù)直接量,ECMAScript v3 定義了函數(shù)直接量,JavaScript 1.2 實現(xiàn)了它。函數(shù)直接量是一個表達式,它即可以定義一個匿名函數(shù),也可以定義一個帶函數(shù)名的函數(shù):
清單 4.
注意:調(diào)用時得用定義的變量名,如f(4),而不能fact(4).
函數(shù)直接量和使用 Function()構(gòu)造函數(shù)來創(chuàng)建函數(shù)的方法非常相似,因為兩種方法都是通過 JavaScript 的表達式創(chuàng)建的,而不是由語句創(chuàng)建的;所以使用他們的方式也更靈活,尤其是那些只使用一次,而且不需要命名的函數(shù)。比如把它傳遞給其他的函數(shù):
清單 5.
三種方式的區(qū)別,可以從作用域、效率以及加載順序來區(qū)分。首先,從作用域上來說,函數(shù)聲明式和函數(shù)直接量使用的是局部變量,而 Function()構(gòu)造函數(shù)卻是全局變量:
清單 6.
其次是執(zhí)行效率上來說,F(xiàn)unction()構(gòu)造函數(shù)的效率要低于其他兩種方式,尤其是在循環(huán)體中,因為構(gòu)造函數(shù)每執(zhí)行一次都要重新編譯,并且生成新的函數(shù)對象:
清單 7.
由此可見,在循環(huán)體中,函數(shù)直接量的執(zhí)行效率是 Function()構(gòu)造函數(shù)的 0.6 倍。所以在 Web 開發(fā)中,為了加快網(wǎng)頁加載速度,提高用戶體驗,我們不建議選擇 Function ()構(gòu)造函數(shù)方式來定義函數(shù)。
最后是加載順序,function 方式(即函數(shù)聲明式)是在 JavaScript 編譯的時候就加載到作用域中,而其他兩種方式則是在代碼執(zhí)行的時候加載,如果在定義之前調(diào)用它,則會返回 undefined:
清單 8.
當深入 JavaScript 編程世界時,您將遇到的基本概念之一是方法和函數(shù)之間的區(qū)別。雖然方法和函數(shù)在 JavaScript 中都起著至關(guān)重要的作用,但它們具有不同的目的并以不同的方式使用。在這篇博文中,我們將揭開這兩個概念的神秘面紗,讓您清楚地了解它們的差異。
讓我們深入了解有關(guān) function 和 method 的更多詳細信息:
function 的核心是執(zhí)行特定任務或一組任務的可重用代碼塊。將其視為一組預定義的指令,您可以在需要時調(diào)用或調(diào)用它們。函數(shù)就像 JavaScript 代碼的構(gòu)建塊,允許您將復雜的任務分解為更小的、可管理的部分。
這是一個函數(shù)的基本示例:
function greet(name) {
return "Hello, " + name + "!";
}
在此代碼段中, greet 是一個函數(shù),它采用單個參數(shù) name ,并返回問候語字符串。 JavaScript 中的函數(shù)用途廣泛,可以在各種上下文中使用,從像這樣的簡單操作到復雜的邏輯。
現(xiàn)在,我們來談談方法。 JavaScript 中的方法本質(zhì)上是一個函數(shù),但有一個關(guān)鍵的區(qū)別——它與一個對象關(guān)聯(lián)。方法是存儲為對象屬性的函數(shù),用于定義該對象的行為。下面舉個例子來說明:
let person={
firstName: "John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
};
在此示例中, fullName 是 person 對象的方法。它使用 this 關(guān)鍵字來訪問對象的屬性。
讓我們重點介紹 JavaScript 中函數(shù)和方法之間的主要區(qū)別:
理解 JavaScript 中 methods 和 functions 之間的區(qū)別對于編寫清晰高效的代碼至關(guān)重要。函數(shù)提供了模塊化和可重用性,而方法則為我們提供了一種遵循面向?qū)ο缶幊淘瓌t將行為封裝在對象內(nèi)的方法。
總之,雖然所有方法都是函數(shù),但并非所有函數(shù)都是方法。區(qū)別在于它們與對象的關(guān)聯(lián)以及它們?nèi)绾卧谶@些對象的上下文中使用。
JavaScript 函數(shù)有 4 種調(diào)用方式。
每種方式的不同方式在于 this 的初始化。
this 關(guān)鍵字
一般而言,在Javascript中,this指向函數(shù)執(zhí)行時的當前對象。
注意 this 是保留關(guān)鍵字,你不能修改 this 的值。 |
調(diào)用 JavaScript 函數(shù)
我們知道如何創(chuàng)建函數(shù)。
函數(shù)中的代碼在函數(shù)被調(diào)用后執(zhí)行。
作為一個函數(shù)調(diào)用
實例
function myFunction(a, b) {
return a * b;
}
myFunction(10, 2); // myFunction(10, 2) 返回 20
以上函數(shù)不屬于任何對象。但是在 JavaScript 中它始終是默認的全局對象。
在 HTML 中默認的全局對象是 HTML 頁面本身,所以函數(shù)是屬于 HTML 頁面。
在瀏覽器中的頁面對象是瀏覽器窗口(window 對象)。以上函數(shù)會自動變?yōu)?window 對象的函數(shù)。
myFunction() 和 window.myFunction() 是一樣的:
實例
function myFunction(a, b) {
return a * b;
}
window.myFunction(10, 2); // window.myFunction(10, 2) 返回 20
這是調(diào)用 JavaScript 函數(shù)常用的方法, 但不是良好的編程習慣 全局變量,方法或函數(shù)容易造成命名沖突的bug。 |
全局對象
當函數(shù)沒有被自身的對象調(diào)用時, this 的值就會變成全局對象。
在 web 瀏覽器中全局對象是瀏覽器窗口(window 對象)。
該實例返回 this 的值是 window 對象:
實例
function myFunction() {
return this;
}
myFunction(); // 返回 window 對象
函數(shù)作為全局對象調(diào)用,會使 this 的值成為全局對象。使用 window 對象作為一個變量容易造成程序崩潰。 |
函數(shù)作為方法調(diào)用
在 JavaScript 中你可以將函數(shù)定義為對象的方法。
以下實例創(chuàng)建了一個對象 (myObject), 對象有兩個屬性 (firstName 和 lastName), 及一個方法 (fullName):
實例
var myObject={
firstName:"John",
lastName: "Doe",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
myObject.fullName(); // 返回 "John Doe"
fullName 方法是一個函數(shù)。函數(shù)屬于對象。 myObject 是函數(shù)的所有者。
this對象,擁有 JavaScript 代碼。實例中 this 的值為 myObject 對象。
測試以下!修改 fullName 方法并返回 this 值:
實例
var myObject={
firstName:"John",
lastName: "Doe",
fullName: function () {
return this;
}
}
myObject.fullName(); // 返回 [object Object] (所有者對象)
函數(shù)作為對象方法調(diào)用,會使得 this 的值成為對象本身。 |
使用構(gòu)造函數(shù)調(diào)用函數(shù)
如果函數(shù)調(diào)用前使用了 new 關(guān)鍵字, 則是調(diào)用了構(gòu)造函數(shù)。
這看起來就像創(chuàng)建了新的函數(shù),但實際上 JavaScript 函數(shù)是重新創(chuàng)建的對象:
實例
// 構(gòu)造函數(shù):
function myFunction(arg1, arg2) {
this.firstName=arg1;
this.lastName=arg2;
}
// Thiscreates a new object
var x=new myFunction("John","Doe");
x.firstName; // 返回 "John"
構(gòu)造函數(shù)的調(diào)用會創(chuàng)建一個新的對象。新對象會繼承構(gòu)造函數(shù)的屬性和方法。
構(gòu)造函數(shù)中 this 關(guān)鍵字沒有任何的值。this 的值在函數(shù)調(diào)用時實例化對象(new object)時創(chuàng)建。 |
作為函數(shù)方法調(diào)用函數(shù)
在 JavaScript 中, 函數(shù)是對象。JavaScript 函數(shù)有它的屬性和方法。
call() 和 apply() 是預定義的函數(shù)方法。 兩個方法可用于調(diào)用函數(shù),兩個方法的第一個參數(shù)必須是對象本身。
實例
function myFunction(a, b) {
return a * b;
}
myFunction.call(myObject, 10, 2); // 返回 20
實例
function myFunction(a, b) {
return a * b;
}
myArray=[10,2];
myFunction.apply(myObject, myArray); // 返回 20
兩個方法都使用了對象本身作為第一個參數(shù)。 兩者的區(qū)別在于第二個參數(shù): apply傳入的是一個參數(shù)數(shù)組,也就是將多個參數(shù)組合成為一個數(shù)組傳入,而call則作為call的參數(shù)傳入(從第二個參數(shù)開始)。
在 JavaScript 嚴格模式(strict mode)下, 在調(diào)用函數(shù)時第一個參數(shù)會成為 this 的值, 即使該參數(shù)不是一個對象。
在 JavaScript 非嚴格模式(non-strict mode)下, 如果第一個參數(shù)的值是 null 或 undefined, 它將使用全局對象替代。
通過 call() 或 apply() 方法你可以設(shè)置 this 的值, 且作為已存在對象的新方法調(diào)用。 |
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。