一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

高級JScript

 duduwolf 2006-05-18
1.創(chuàng)建高級對象
使用構(gòu)造函數(shù)來創(chuàng)建對象
構(gòu)造函數(shù)是一個(gè)函數(shù),調(diào)用它來例示并初始化特殊類型的對象??梢允褂?nbsp;new 關(guān)鍵字來調(diào)用一個(gè)構(gòu)造函數(shù)。下面給出了使用構(gòu)造函數(shù)的新示例。

var myObject = new Object();             // 創(chuàng)建沒有屬性的通用對象。
var myBirthday = new Date(1961, 5, 10);  // 創(chuàng)建一個(gè) Date 對象。
var myCar = new Car();                   // 創(chuàng)建一個(gè)用戶定義的對象,并初始化其屬性。
通過構(gòu)造函數(shù)將一個(gè)參數(shù)作為特定的 this 關(guān)鍵字的值傳遞給新創(chuàng)建的空對象。然后構(gòu)造函數(shù)負(fù)責(zé)為新對象執(zhí)行適應(yīng)的初始化(創(chuàng)建屬性并給出其初始值)。完成后,構(gòu)造函數(shù)返回它所構(gòu)造的對象的一個(gè)參數(shù)。

編寫構(gòu)造函數(shù)
可以使用 new 運(yùn)算符結(jié)合像 Object()、Date() 和 Function() 這樣的預(yù)定義的構(gòu)造函數(shù)來創(chuàng)建對象并對其初始化。面向?qū)ο蟮木幊唐鋸?qiáng)有力的特征是定義自定義構(gòu)造函數(shù)以創(chuàng)建腳本中使用的自定義對象的能力。創(chuàng)建了自定義的構(gòu)造函數(shù),這樣就可以創(chuàng)建具有已定義屬性的對象。下面是自定義函數(shù)的示例(注意 this 關(guān)鍵字的使用)。

function Circle (xPoint, yPoint, radius) {
    this.x = xPoint;  // 圓心的 x 坐標(biāo)。
    this.y = yPoint;  // 圓心的 y 坐標(biāo)。
    this.r = radius;  // 圓的半徑。
}
調(diào)用 Circle 構(gòu)造函數(shù)時(shí),給出圓心點(diǎn)的值和圓的半徑(所有這些元素是完全定義一個(gè)獨(dú)特的圓對象所必需的)。結(jié)束時(shí) Circle 對象包含三個(gè)屬性。下面是如何例示 Circle 對象。

var aCircle = new Circle(5, 11, 99);
使用原型來創(chuàng)建對象
在編寫構(gòu)造函數(shù)時(shí),可以使用原型對象(它本身是所有構(gòu)造函數(shù)的一個(gè)屬性)的屬性來創(chuàng)建繼承屬性和共享方法。原型屬性和方法將按引用復(fù)制給類中的每個(gè)對象,因此它們都具有相同的值??梢栽谝粋€(gè)對象中更改原型屬性的值,新的值將覆蓋默認(rèn)值,但僅在該實(shí)例中有效。屬于這個(gè)類的其他對象不受此更改的影響。下面給出了使用自定義構(gòu)造函數(shù)的示例,Circle(注意 this 關(guān)鍵字的使用)。

Circle.prototype.pi = Math.PI;
function ACirclesArea () {
    return this.pi * this.r * this.r; // 計(jì)算圓面積的公式為 ?r2。
}
Circle.prototype.area = ACirclesArea; // 計(jì)算圓面積的函數(shù)現(xiàn)在是 Circle Prototype 對象的一個(gè)方法。
var a = ACircle.area();               // 此為如何在 Circle 對象上調(diào)用面積函數(shù)。
使用這個(gè)原則,可以給預(yù)定義的構(gòu)造函數(shù)(都具有原型對象)定義附加屬性。例如,如果想要能夠刪除字符串的前后空格(與 VBScript 的 Trim 函數(shù)類似),就可以給 String 原型對象創(chuàng)建自己的方法。

// 增加一個(gè)名為 trim 的函數(shù)作為
// String 構(gòu)造函數(shù)的原型對象的一個(gè)方法。
String.prototype.trim = function()
{
    // 用正則表達(dá)式將前后空格
    // 用空字符串替代。
    return this.replace(/(^\s*)|(\s*$)/g, "");
}

// 有空格的字符串
var s = "    leading and trailing spaces    ";

// 顯示 "    leading and trailing spaces     (35)"
window.alert(s + " (" + s.length + ")");

// 刪除前后空格
s = s.trim();
// 顯示"leading and trailing spaces (27)"
window.alert(s + " (" + s.length + ")");

2.遞歸
遞歸是一種重要的編程技術(shù)。該方法用于讓一個(gè)函數(shù)從其內(nèi)部調(diào)用其自身。一個(gè)示例就是計(jì)算階乘。0 的階乘被特別地定義為 1。 更大數(shù)的階乘是通過計(jì)算 1 * 2 * ...來求得的,每次增加 1,直至達(dá)到要計(jì)算其階乘的那個(gè)數(shù)。

下面的段落是用文字定義的計(jì)算階乘的一個(gè)函數(shù)。

“如果這個(gè)數(shù)小于零,則拒絕接收。如果不是一個(gè)整數(shù),則將其向下舍入為相鄰的整數(shù)。如果這個(gè)數(shù)為 0,則其階乘為 1。如果這個(gè)數(shù)大于 0,則將其與相鄰較小的數(shù)的階乘相乘。”

要計(jì)算任何大于 0 的數(shù)的階乘,至少需要計(jì)算一個(gè)其他數(shù)的階乘。用來實(shí)現(xiàn)這個(gè)功能的函數(shù)就是已經(jīng)位于其中的函數(shù);該函數(shù)在執(zhí)行當(dāng)前的這個(gè)數(shù)之前,必須調(diào)用它本身來計(jì)算相鄰的較小數(shù)的階乘。這就是一個(gè)遞歸示例。

遞歸和迭代(循環(huán))是密切相關(guān)的 ? 能用遞歸處理的算法也都可以采用迭代,反之亦然。確定的算法通??梢杂脦追N方法實(shí)現(xiàn),您只需選擇最自然貼切的方法,或者您覺得用起來最輕松的一種即可。

顯然,這樣有可能會出現(xiàn)問題??梢院苋菀椎貏?chuàng)建一個(gè)遞歸函數(shù),但該函數(shù)不能得到一個(gè)確定的結(jié)果,并且不能達(dá)到一個(gè)終點(diǎn)。這樣的遞歸將導(dǎo)致計(jì)算機(jī)執(zhí)行一個(gè)“無限”循環(huán)。下面就是一個(gè)示例:在計(jì)算階乘的文字描述中遺漏了第一條規(guī)則(對負(fù)數(shù)的處理) ,并試圖計(jì)算任何負(fù)數(shù)的階乘。這將導(dǎo)致失敗,因?yàn)榘错樞蛴?jì)算 -24 的階乘時(shí),首先不得不計(jì)算 -25 的階乘;然而這樣又不得不計(jì)算 -26 的階乘;如此繼續(xù)。很明顯,這樣永遠(yuǎn)也不會到達(dá)一個(gè)終止點(diǎn)。

因此在設(shè)計(jì)遞歸函數(shù)時(shí)應(yīng)特別仔細(xì)。如果懷疑其中存在著無限遞歸的可能,則可以讓該函數(shù)記錄它調(diào)用自身的次數(shù)。如果該函數(shù)調(diào)用自身的次數(shù)太多,即使您已決定了它應(yīng)調(diào)用多少次,就自動退出。

下面仍然是階乘函數(shù),這次是用 JScript 代碼編寫的。 

// 計(jì)算階乘的函數(shù)。如果傳遞了
// 無效的數(shù)值(例如小于零),
// 將返回 -1,表明發(fā)生了錯(cuò)誤。若數(shù)值有效,
// 把數(shù)值轉(zhuǎn)換為最相近的整數(shù),并
// 返回階乘。
function factorial(aNumber)  {
aNumber = Math.floor(aNumber);  // 如果這個(gè)數(shù)不是一個(gè)整數(shù),則向下舍入。
if (aNumber < 0)  {  // 如果這個(gè)數(shù)小于 0,拒絕接收。
    return -1;
    }
      if (aNumber == 0)  {  // 如果為 0,則其階乘為 1。
      return 1;
      }
        else return (aNumber * factorial(aNumber - 1));  // 否則,遞歸直至完成。
}

3.變量范圍
JScript 有兩種變量范圍:全局和局部。如果在任何函數(shù)定義之外聲明了一個(gè)變量,則該變量為全局變量,且該變量的值在整個(gè)持續(xù)范圍內(nèi)都可以訪問和修改。如果在函數(shù)定義內(nèi)聲明了一個(gè)變量,則該變量為局部變量。每次執(zhí)行該函數(shù)時(shí)都會創(chuàng)建和破壞該變量;且它不能被該函數(shù)外的任何事物訪問。

像 C++ 這樣的語言也有“塊范圍”。在這里,任何一對“{}”都定義新的范圍。JScript 不支持塊范圍。

一個(gè)局部變量的名稱可以與某個(gè)全局變量的名稱相同,但這是完全不同和獨(dú)立的兩個(gè)變量。因此,更改一個(gè)變量的值不會影響另一個(gè)變量的值。在聲明局部變量的函數(shù)內(nèi),只有該局部變量有意義。 

var aCentaur = "a horse with rider,";  // aCentaur 的全局定義。

// JScript 代碼,為簡潔起見有省略。
function antiquities()  // 在這個(gè)函數(shù)中聲明了一個(gè)局部 aCentaur 變量。
{

// JScript 代碼,為簡潔起見有省略。
var aCentaur = "A centaur is probably a mounted Scythian warrior";

// JScript 代碼,為簡潔起見有省略。
   aCentaur += ", misreported; that is, ";  // 添加到局部變量。

// JScript 代碼,為簡潔起見有省略。
}  // 函數(shù)結(jié)束。

var nothinginparticular = antiquities();
aCentaur += " as seen from a distance by a naive innocent.";

/*
在函數(shù)內(nèi),該變量的值為 "A centaur is probably a mounted Scythian warrior,
misreported; that is, ";在函數(shù)外,該變量的值為這句話的其余部分:
"a horse with rider, as seen from a distance by a naive innocent."
*/  
很重要的一點(diǎn)是注意變量是否是在其所屬范圍的開始處聲明的。有時(shí)這會導(dǎo)致意想不到的情況。 

tweak();
var aNumber = 100;
function tweak()  {
var newThing = 0;  // 顯式聲明 newThing 變量。

    // 本語句將未定義的變量賦給 newThing,因?yàn)橐延忻麨?nbsp;aNumber 的局部變量。
    newThing = aNumber;

    //下一條語句將值 42 賦給局部的 aNumber。aNumber = 42;
if (false)  {
    var aNumber;  // 該語句永遠(yuǎn)不會執(zhí)行。
    aNumber = 123;  //  該語句永遠(yuǎn)不會執(zhí)行。
    }  // 條件語句結(jié)束。

}  // 該函數(shù)定義結(jié)束。
當(dāng) JScript 運(yùn)行函數(shù)時(shí),首先查找所有的變量聲明,

var someVariable;
并以未定義的初始值創(chuàng)建變量。如果變量被聲明時(shí)有值,

var someVariable = "something";
那么該變量仍以未定義的值初始化,并且只有在運(yùn)行了聲明行時(shí)才被聲明值取代,假如曾經(jīng)被聲明過。

JScript 在運(yùn)行代碼前處理變量聲明,所以聲明是位于一個(gè)條件塊中還是其他某些結(jié)構(gòu)中無關(guān)緊要。JScript 找到所有的變量后立即運(yùn)行函數(shù)中的代碼。如果變量是在函數(shù)中顯式聲明的 ? 也就是說,如果它出現(xiàn)于賦值表達(dá)式的左邊但沒有用 var 聲明 ? 那么將把它創(chuàng)建為全局變量。
復(fù)制、傳遞和比較數(shù)據(jù)
在 JScript 中,對數(shù)據(jù)的處理取決于該數(shù)據(jù)的類型。 

按值和按引用的比較
Numbers 和 Boolean 類型的值 (true 和 false) 是按值來復(fù)制、傳遞和比較的。當(dāng)按值復(fù)制或傳遞時(shí),將在計(jì)算機(jī)內(nèi)存中分配一塊空間并將原值復(fù)制到其中。然后,即使更改原來的值,也不會影響所復(fù)制的值(反過來也一樣),因?yàn)檫@兩個(gè)值是獨(dú)立的實(shí)體。

對象、數(shù)組以及函數(shù)是按引用來復(fù)制、傳遞和比較的。 當(dāng)按地址復(fù)制或傳遞時(shí),實(shí)際是創(chuàng)建一個(gè)指向原始項(xiàng)的指針,然后就像拷貝一樣來使用該指針。如果隨后更改原始項(xiàng),則將同時(shí)更改原始項(xiàng)和復(fù)制項(xiàng)(反過來也一樣)。實(shí)際上只有一個(gè)實(shí)體;“復(fù)本”并不是一個(gè)真正的復(fù)本,而只是該數(shù)據(jù)的又一個(gè)引用。

當(dāng)按引用比較時(shí),要想比較成功,兩個(gè)變量必須參照完全相同的實(shí)體。例如,兩個(gè)不同的 Array 對象即使包含相同的元素也將比較為不相等。要想比較成功,其中一個(gè)變量必須為另一個(gè)的參考。要想檢查兩個(gè)數(shù)組是否包含了相同的元素,比較 toString() 方法的結(jié)果。

最后,字符串是按引用復(fù)制和傳遞的,但是是按值來比較的。請注意,假如有兩個(gè) String 對象(用 new String("something") 創(chuàng)建的),按引用比較它們,但是,如果其中一個(gè)或者兩者都是字符串值的話,按值比較它們。

注意   鑒于 ASCII和 ANSI 字符集的構(gòu)造方法,按序列順序大寫字母位于小寫字母的前面。例如 "Zoo" 小于 "aardvark"。如果想執(zhí)行不區(qū)分大小寫的匹配,可以對兩個(gè)字符串調(diào)用 toUpperCase() 或 toLowerCase()。

傳遞參數(shù)給函數(shù)
按值傳遞一個(gè)參數(shù)給函數(shù)就是制作該參數(shù)的一個(gè)獨(dú)立復(fù)本,即一個(gè)只存在于該函數(shù)內(nèi)的復(fù)本。即使按引用傳遞對象和數(shù)組時(shí),如果直接在函數(shù)中用新值覆蓋原先的值,在函數(shù)外并不反映新值。只有在對象的屬性或者數(shù)組的元素改變時(shí),在函數(shù)外才可以看出。

例如(使用 IE 對象模式):

// 本代碼段破壞(覆蓋)其參數(shù),所以
// 調(diào)用代碼中反映不出變化。
function Clobber(param) 
{
    // 破壞參數(shù);在調(diào)用代碼中
    // 看不到。
    param = new Object();
    param.message = "This will not work";
}

// 本段代碼改變參數(shù)的屬性,
// 在調(diào)用代碼中可看到屬性改變。
function Update(param)
{
    // 改變對象的屬性;
    // 可從調(diào)用代碼中看到改變。
    param.message = "I was changed";
}

// 創(chuàng)建一個(gè)對象,并賦給一個(gè)屬性。
var obj = new Object();
obj.message = "This is the original";

// 調(diào)用 Clobber,并輸出 obj.message。注意,它沒有發(fā)生變化。
Clobber(obj);
window.alert(obj.message); // 仍然顯示 "This is the original"。

// 調(diào)用 Update,并輸出 obj.message。注意,它已經(jīng)被改變了。
Update(obj);
window.alert(obj.message); // 顯示 "I was changed"。
檢驗(yàn)數(shù)據(jù)
當(dāng)按值進(jìn)行檢驗(yàn)時(shí),是比較兩個(gè)截然不同的項(xiàng)以查看它們是否相等。通常,該比較是逐字節(jié)進(jìn)行的。當(dāng)按引用進(jìn)行檢驗(yàn)時(shí),是看這兩項(xiàng)是否是指向同一個(gè)原始項(xiàng)的指針。如果是,則比較結(jié)果是相等;如果不是,即使它們每個(gè)字節(jié)都包含完全一樣的值,比較結(jié)果也為不相等。

按引用復(fù)制和傳遞字符串能節(jié)約內(nèi)存;但是由于在字符串被創(chuàng)建后不能進(jìn)行更改,因此可以按值進(jìn)行比較。這樣可以檢查兩個(gè)字符串是否包含相同的內(nèi)容,即使它們是完全獨(dú)立產(chǎn)生的。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    久久女同精品一区二区| 久久精视频免费视频观看| 真实偷拍一区二区免费视频| 精品国产丝袜一区二区| 国内九一激情白浆发布| 亚洲中文字幕剧情在线播放| 成人午夜激情在线免费观看| 亚洲成人精品免费在线观看| 亚洲精品欧美精品一区三区| 久久re6热在线视频| 国产农村妇女成人精品| 亚洲中文字幕剧情在线播放| 三级理论午夜福利在线看| 欧美人妻免费一区二区三区| 精品久久久一区二区三| 久久99爱爱视频视频| 亚洲最新一区二区三区| 日韩av欧美中文字幕| 亚洲伊人久久精品国产| 亚洲一区二区三区三州| 神马午夜福利一区二区| 国产精品一区欧美二区| 午夜福利大片亚洲一区| 老司机精品视频免费入口| 欧美一级特黄大片做受大屁股| 免费一级欧美大片免费看| 午夜视频免费观看成人| 黄色美女日本的美女日人| 国产成人亚洲综合色就色| 深夜视频在线观看免费你懂| 国产欧美一区二区另类精品| 国产精品亚洲综合天堂夜夜| 国产精品一区二区传媒蜜臀| 亚洲熟妇av一区二区三区色堂 | 最近日韩在线免费黄片| 精品国产一区二区欧美| 亚洲做性视频在线播放| 儿媳妇的诱惑中文字幕| 国产又色又爽又黄的精品视频| 欧美精品久久男人的天堂| 亚洲专区中文字幕视频|