javascript的函數第1/3頁

來源:互聯網
上載者:User

作者:F. Permadi
譯者:Sheneyan(子烏)
英文原文: INTRODUCTION TO JavaScript Functions
中文譯文(包括樣本):javascript的函數
子烏註:一篇相當不錯的function入門文章,個人感覺相當經典。

詞語翻譯列表:

function:函數(Function未翻譯)
declare:定義
assign:指派,分配
functionbody:函數體(就是函數的內容)
object:對象
property:屬性
unnamed:匿名(在這裡沒翻譯成未命名)
object oriented programming:面相對相編程
class:類(比如後面的class data type我翻譯成類資料類型)
pointer:指標
reassign:重新分配
nest:嵌套
feature:功能,特性
local/global:局部/全域
blueprint:藍圖(?)
user defined:使用者自訂
instance:執行個體
prototype:原型(除了標題都不翻譯)
internal:內部
constructor:構造器
duplication:

函數:定義

有以下這些方法可以定義一個函數。所有這些都是有效,但是它們在後台如何?的則有一些差別。

常用的寫法

一般大家都用這個寫法來定義一個函數:

CODE:
functionName([parameters]){functionBody};

Example D1:

CODE:
function add(a, b)
{
return a+b;
}
alert(add(1,2)); // 結果 3

當我們這麼定義函數的時候,函數內容會被編譯(但不會立即執行,除非我們去調用它)。而且,也許你不知道,當這個函數建立的時候有一個同名的對象也被建立。就我們的例子來說,我們現在有一個對象叫做“add”(要更深入瞭解,看底下函數:對象節。)

匿名函數

我們也可以通過指派一個變數名給匿名函數的方式來定義它。

Example D2

CODE:
var add=function(a, b)
{
return a+b;
}
alert(add(1,2)); // 結果 3

這個代碼和前一個例子做了同樣的事情。也許文法看起來比較奇怪,但它應該更能讓你感覺到函數是一個對象,而且我們只是為這個對指派了一個名稱。可以把它看做和 var myVar=[1,2,3]一樣的語句。以這種方式聲明的函數內容也一樣會被編譯。

當我們指派一個這樣的函數的時候,我們並不一定要求必須是匿名函數。在這裡,我作了和ExampleD2一樣的事情,但我加了函數名“theAdd”,而且我可以通過調用函數名或者是那個變數來引用函數。

Example D2A

CODE:
var add=function theAdd(a, b)
{
return a+b;
}
alert(add(1,2)); // 結果 3
alert(theAdd(1,2)); // 結果也是 3

使用這種方式來定義函數在物件導向編程中是很有用的,因為我們能像底下這樣使一個函數成為一個對象的屬性。

CODE:
var myObject=new Object();
myObject.add=function(a,b){return a+b};
// myObject 現在有一個叫做“add”的屬性(或方法)
// 而且我能夠象下面這樣使用它
myObject.add(1, 2);

我們也能夠通過使用運算子new來定義一個函數。這是一個最少見的定義函數的方式並且並不推薦使用這種方式除非有特殊的理由(可能的理由見下)。文法如下:

CODE:
varName=new Function([param1Name, param2Name,...paramNName], functionBody);

Example D3:

CODE:
var add=new Function("a", "b", "return a+b;");
alert(add(3,4)); // 結果 7

我在這裡有兩個參數叫做a和b,而函數體返回a和b的和。請注意new Function(...)使用了大寫F,而不是小寫f。 這就告訴javascript,我們將要建立一個類型是Function的對象。 還要注意到,參數名和函數體都是作為字串而被傳遞。我們可以隨心所欲的增加參數,javascript知道函數體會是右括弧前的最後一個字串(如果沒有參數,你能夠唯寫函數體)。你沒必要將所有東西都寫在一行裡(使用\或者使用字串串連符+來分隔長代碼)。\標記告訴JavaScript在下一行尋找字串的其餘部分。例子如下:

Example D4

CODE:
var add=new Function("a", "b",
"alert" + // 注意 "+"
"('adding '+a+' and ' +b);\ // 和 "\"的不同用法
return a+b;");
alert(add(3,4)); // 結果 7

採用這種方式定義函數會導致函數並沒被編譯,而且它有可能會比用其它方式定義的函數要慢。至於為什麼,看一下這個代碼:

Example D5

CODE:

function createMyFunction(myOperator)
{
return new Function("a", "b", "return a" + myOperator + "b;");
}

var add=createMyFunction("+"); // 建立函數 "add"
var subtract=createMyFunction("-"); // 建立函數 "subtract"
var multiply=createMyFunction("*"); // 建立函數 "multiply"
// test the functions
alert("加的結果="+add(10,2)); // 結果是 12
alert("減的結果="+subtract(10,2)); // 結果是 8
alert("乘的結果="+multiply(10,2)); // 結果是 20
alert(add);

這個有趣的例子建立了三個不同的function,通過即時傳遞不同的參數來建立一個新Function。因為編譯器沒法知道最終代碼會是什麼樣子的,所以new Function(...)的內容不會被編譯。那這有什麼好處呢?嗯,舉個例子,如果你需要使用者能夠建立他們自己的函數的時候這個功能也許很有用,比如在遊戲裡。我們也許需要允許使用者添加“行為”給一個“player”。但是,再說一次,一般情況下,我們應該避免使用這種形式,除非有一個特殊的目的。

函數:對象

函數是javascript中的一種特殊形式的對象。它是第一個[b〕類資料類型(class data type)。這意味著我們能夠給它增加屬性。這裡有一些需要注意的有趣觀點:

對象的建立

就像剛才提及的,當我們定義一個函數時,javascript實際上在後台為你建立了一個對象。這個對象的名稱就是函數名本身。這個對象的類型是function。在下面的例子,我們也許不會意識到這一點,但我們實際上已經建立了一個對象:它叫做Ball。

Example 1

CODE:
function Ball() // 也許看起來有點奇怪,但是這個聲明
{ // 建立了一個叫做Ball的對象
i=1;
}
alert(typeof Ball); // 結果 "function"

我們甚至能將這個對象的內容列印出來而且它會輸出這個函數的實際代碼,Example2: 點擊 alert(Ball);來看看Ball的內容。

屬性的添加

我們能夠添加給Object添加屬性,包括對象function。因為定義一個函數的實質是建立一個對象。我們能夠“暗地裡”給函數添加屬性。比如,我們這裡定義了函數Ball,並添加屬性callsign。

CODE:
function Ball() // 也許看起來有點奇怪,但是這個聲明
{ // 建立了一個叫做Ball的對象,而且你能夠
} // 引用它或者象下面那樣給它增加屬性
Ball.callsign="The Ball"; // 給Ball增加屬性
alert(Ball.callsign); // 輸出 "The Ball"

指標

因為function是一個對象,我們能夠為一個function分配一個指標。如下例,變數ptr指向了對象myFunction。

CODE:
function myFunction(message)
{
alert(message);
}
var ptr=myFunction; // ptr指向了myFunction
ptr("hello"); // 這句會執行myFunction:輸出"hello"

我們能夠運行這個函數,就好像這個函數名已經被指標名代替了一樣。所以在上面,這行ptr("hello"); 和myFunction("hello");的意義是一樣的。

指向函數的指標在物件導向編程中相當有用。例如:當我們有多個對象指向同一個函數的時候(如下):

Example 4A

CODE:
function sayName(name)
{
alert(name);
}
var object1=new Object(); // 建立三個對象
var object2=new Object();
var object3=new Object();
object1.sayMyName=sayName; // 將這個函數指派給所有對象
object2.sayMyName=sayName;
object3.sayMyName=sayName;

object1.sayMyName("object1"); // 輸出 "object1"
object2.sayMyName("object2"); // 輸出 "object2"
object3.sayMyName("object3"); // 輸出 "object3"

因為只有指標被儲存(而不是函數本身),當我們改變函數對象自身的時候,所有指向那個函數的指標都會發生變化。我們能夠在底下看到:

Example 5:

CODE:

function myFunction()
{
alert(myFunction.message);
}
myFunction.message="old";
var ptr1=myFunction; // ptr1 指向 myFunction
var ptr2=myFunction; // ptr2 也指向 myFunction

ptr1(); // 輸出 "old"
ptr2(); // 輸出 "old"

myFunction.message="new";

ptr1(); // 輸出 "new"
ptr2(); // 輸出 "new"

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.