縱覽 JavaScript語言(不敢獨享)

來源:互聯網
上載者:User
文章目錄
  • 對象
  • 數組
  • 定義函數
  • 全域對象
  • 分號的插入時機
  • 預留字

轉載:http://svza.blogspot.com/2007/03/javascript_09.html  這裡格式可能好看點(這個好像得.翻.牆.)

順便奉送:http://dancewithnet.com/snapshot/code-conventions-for-the-javascript-programming-language/

簡介

這篇文章是為專業程式員介紹的JavaScript語言的,它是一種小巧的語言,如果你熟悉其他的程式設計語言,那麼這篇文章對你來講不是那麼難以理解。

JavaScript不是Java,他們是兩門完全不同的語言,JavaScript不是Java的子集,JavaScript不能被認為是Java(Java就是Java)。JavaScript分享了像Java一樣分享C語言的文法,但從更深角度講JavaScript更與Scheme和Self有相似之處。它是一門小巧的語言,但是它確實強大的和豐富的語言。你應該好好觀察一下它,你會發現它不是一個玩具語言,而是一個擁有許多與眾不同特性的、完整的語言。

JavaScript是一門不用花太多時間學習的正規語言。它能更好地適合一些任務,比如與Java相比它更適合用戶端編程。以我的實踐經驗,我發現用JavaScript工作使我成為一個更好的Java程式員,因為它給我帶來一套豐富的技巧。

當我最初接觸JavaScript時,我沒有理他以為它不值得我的注意。後來,我對它刮目相看,因為我發現隱藏在瀏覽器中的它是一個如此有效程式語言。我最初是在JavaScript在Sun和Netscape公司的初始陳述注意到它的。他們對JavaScript做了許多錯誤陳述,以免使它和Java處於競爭的位置。這些錯誤陳述繼續充斥這那些只為傀儡和業餘愛好者提供的、不好的JavaScript書中。

曆史

JavaScript是被Netscape的Brendan Eich,作為一個頁面指令碼語言,在Navigator 2中開發的。它是一個非常具有表現力的動態程式語言,因為和瀏覽器的關係,它立刻變的大紅大紫了。它從來沒有得到一個可以校正它的問題的和基於真正使用目的測試周期,這一切導致它很強大卻也有缺陷。

這篇文章描述了ECMAScript 版本3 (也叫 JavaScript 1.5)。 Microsoft和Netscape一起開發了一個沒有改正缺陷的獃滯版本。新版本的語言也許不能叫JavaScript,也不在這篇文章的討論範圍內。

資料類型

JavaScript包含一小套資料類型,它有3種簡單的類型:boolean,number, 和 string;特殊的值:null,undefined;其他的所有基於object類型的變化。

布爾類型有2個值:truefalse

數字是64位的浮點值,與Java的Double類似。它沒有整型。除法運算可能帶來小數位的結果。數字包括特殊值NaN(不是一個數字)和Infinity

字串(string)是從零到多個Unicode字元組成的。沒有單獨的位元組類型。一個位元組被描繪成一個長度為1的字串。字串被'符號或"符號引用到一起,單引號和雙引號可以替換使用,但必須前後匹配使用。

'This is a string.'
"Isn't this a string? Yes!"
'A' // The character A
"" // An empty string

轉義用\字元,就像Java一樣。字串是不可變的。字串有一個length屬性類查看字串的用字元的個數。

var s = "Hello World!";s.length == 12

可以給這些簡單類型增加函數,你可以為所有數字類型增加一個int()的函數,當你調用Math.PI.int()的時候就會得到3這個結果。

一個實現可能提供其它類型,比如日期(Dates)類型,Regex類型,但是他們真正的類型是Object類型,所有其它類型都是Object類型。

對象

JavaScript擁有非常漂亮的符號便利以對付那些索引值集合(雜湊表)(hashtables)。

var myHashtable = {};

這條語句了聲明了一個索引值集合,並把它分配到一個局部變數裡。JavaScript是弱類型的,所以我們不能用類型的名稱來進行聲明。我們用索引的方式從索引值結合中增加、替換和擷取對象。

myHashtable["name"] = "Carl Hollywood";

也可以使用“.”的方式帶來一點便利。

myHashtable.city = "Anytown";

當索引是一個合法的系統保留字時,點符號就變得沒用了。這是因為一個語言上的定義錯誤,保留字不能被用於點符號的形勢下,但是可以用於索引的形式下。

你會發現JavaScript的雜湊表符號與Java的對象和數組符號非常地相似。JavaScript把這更發揚廣大了:對象和雜湊表是一個回事,所以我可以這樣寫

var myHashtable = new Object();

這個結果確實是一樣的。

用for語句可以實現對象一個枚舉的能力。

for (var n in myHashtable) {    if (myHashtable.hasOwnProperty(n)) {        document.writeln("<p>" + n + ": " + myHashtable[n] + "</p>");    }}

這個結果應該是

<p>name: Carl Hollywood</p><p>city: Anytown</p>

一個對象就是一個涉及到鍵/值對的集合,鍵是字串(或者其他的元素比如那些被轉化為字串的數字),值可以是任何資料類型,包括其他對象。對象經常以雜湊表的方式實現,但是沒有任何雜湊表(比如雜湊函數或重寫的函數)天性的可見。

對象很容易被嵌套到別的對象當中,並且對象的運算式可以內容對象裡使用。

this.div = document.body.children[document.body.children.length - 1];

對象的文字表達中,一個對象描述了包含在大括弧中的一組用逗點隔開的鍵/值對。鍵可以是在其後用冒號的標識符或字串。由於語言定義的錯誤,系統預留字不能以標識符方式出現,但可以用字串方式出現。值可以是任何類型的文字或運算式。

var myObject = {name: "Jack B. Nimble", 'goto': 'Jail', grade: 'A', level: 3};
return {    event: event,    op: event.type,    to: event.srcElement,    x: event.clientX + document.body.scrollLeft,    y: event.clientY + document.body.scrollTop};
emptyObject = {};

JavaScript的對象模式是JSON的資料交換格式的基礎。

新的成員可以在任何時候被附著增加到任何對象上。

myObject.nickname = 'Jackie the Bee';

數組和函數以對象方式實現。

數組

JavaScript中數組也是雜湊表對象,這使它非常好地與稀少的數組程式相稱。當你聲明了一個數組,你不需要聲明它的大小,數組會自增長,這很像Java的向量(vectors)。數組的值根據鍵來定位,而不是根據位移量,這使JavaScript數組非常方便地使用,但不適合那些數字分析應用。

對象和數組最主要的不同點是length屬性。length屬性總是比最大的整數鍵大1。有2種方式建立一個新數組。

var myArray = [];var myArray = new Array();

數組不是強型別,它可以包括數字、字串、布爾值、對象、函數和數組,你可以在一個數組中混合使用字串、數字和對象。你以嵌套序列的方式使用數組,這和s-expressions的方式非常地類似。數組的第一個索引通常用0。

當數組增加一個新元素的時候,它的索引是比數組長度。然後數組的長度變成在索引基礎上加1。這個便利的特性使數組很容易在for迴圈中增加元素的數量。

數組有個與對象類似的符號標記。

myList = ['oats', 'peas', 'beans', 'barley'];emptyArray = [];month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];slides = [    {url: 'slide0001.html', title: 'Looking&nbsp;Ahead'},    {url: 'slide0008.html', title: 'Forecast'},    {url: 'slide0021.html', title: 'Summary'}];

新元素以分配的方式增加到數組中。

a[i + j] = f(a[i], a[j]);
函數

JavaScript的函數看起來想C語言的函數一樣,但JavaScript用function聲明而不是類型關鍵字。當調用一個函數時,傳遞指定數目的參數不是必須的,過度的參數會被忽略,丟失的參數被賦值為undefined,這使寫一個處理選擇性參數的函數變的很容易。

一個函數有權使用一個參數數組,這個數組包含了所有的實際上被調用傳遞進來的參數。這使處理一個帶可變數目的參數變的很容易,例如:

function sum() {  // Take any number of parameters and return the sum    var total = 0;    for (var i = 0; i < arguments.length; ++i) {        total += arguments[i];    }    return total;}

JavaScript有內建函式,這與Java的內部類起了相同的作用,但是不是那麼地明顯。JavaScript也有也有扮演著lambda運算式的匿名函數。函數有詞法上的範圍。

函數是對象的第一課,這意味著函數可以被儲存在對象中,並且作為參數傳遞給其它函數。

定義函數

有3種方式定義一個函數:function聲明,function操作符和function構造器。

function聲明

function聲明在當前的範圍內建立一個被命名的函數。

function name(argumentlistblock

函數可以嵌套,必須閉合,有0個或多個以逗號隔開的參數名稱。block是由0個或多個{ }附著著。

function聲明以function操作符形式速記:

var name = function name (argumentlistblock ;

function操作符

function操作符是一個產生一個對象的首碼操作符,它看起來和function聲明很類似。

function name(argumentlistblock

名稱是可選的,如果提供了,那麼可以用於函數的遞迴調用。這也用於訪問函數的對象成員(除了IE以外)。如果名稱被省略了,那麼它就是一個匿名函數。

函數的操作符經常用於把它分配給一個原型(prototype)。

函數的操作符也經常用於在適當的地方定義函數,比迅速地得到當寫回調的時候。( The function operator can also be used to define functions in-place, which is handy when writing callbacks.)

function構造器

function構造器攜帶字元包含在參數和內部,從而產生一個function對象。

new Function(strings...)

不要使用這種方式,由於語言引用的慣例導致很難恰當的表達一個函數身體作為一個字串。在字元形式中,早期的錯誤檢查不起作用。這也是很慢的,因為編譯器必須被觸發每當構造器被調用的時候,並且這樣浪費記憶體,因為每個函數需要它自己獨立的實現。

對象和this

一個函數是一個對象,它可以包含成員就像其它對象一樣。這就允許一個函數包含它自己的資料表,這也允許一個對象扮演一個“類”,包含建構函式和一套相關的函數。

一個方式可以是一個對象的成員,當一個函數是一個對象的成員的時候,被成為“方法”。有一個特殊的變數,叫做“this”,當一個對象的方式被調用時指向了對象。

例如:在運算式foo.bar()中,this變數就指向了對象foo,它作為了函數bar的一個額外的參數。函數bar可以使用this進入對象內部以找到有用的項目。

一個深一點的表示式do.re.mi.fa(),this變數指向了對象do.re.mi,而不是對象do。在一個簡單的函數調用中,this指向了沒有太大用的Global Object (也叫 window)。當調用一個內建函式時,正確的行為是保護好當前this的值。

構造器

當函數被用於初始化對象的時候被叫做構造器,調用一個構造器的次序與調用一個普通的函數有一些細微的不同。一個構造器帶著new首碼被調用:

new Constructor(parameters...)

根據習慣,構造器的名字的首字母使用大寫的。

new首碼改變了this 的含義,不是平常的值,而是代表了“新對象”。構造器的身體將會初始化對象的成員。構造起將會返回一個新對象,除非明確的使用了return語句進行替換。

被構造的對象將會包含一個秘密的指向了構造器的prototype的成員的原型連結域。

原型(Prototype)

對象包含一個隱藏的串連屬性,這個連結指向了prototype,就是構造器的執行個體。

當條目以點形式或索引形式從一個對象被訪問的時候,如果條目沒有在對象中被發現那麼就檢查他的連結化物件,如果連結化物件中也沒發現,那麼如果連結化物件本身有一個連結化物件,那麼就繼續檢查這個連結化物件,如果連結化物件所有環節都檢查完畢,那麼就返回undefined。

原型用於連結住一系列的繼承

成員可以用分配的方式增加到prototype中來,這我們定義一個類Demo,它從Ancestor繼承,並增加了它專屬的方法foo。

function Demo() {}Demo.prototype = new Ancestor();Demo.prototype.foo = function () {};
變數

定義變數使用var語句。當變數在函數內部定義時,var有著函數範圍(function-scope)層級,這個變數不能在函數外被訪問。JavaScript中沒有其他的範圍域粒度了,更具體的說,JavaScript中沒有塊域(block-scope)

任何在函數中使用但沒有用var明確定義的變數,都會被假定屬於全域對象。

任何沒有被明確初始化的變數都會被賦值於undefined。

變數不是強型別的,一個變數引用一個對象、字串、數字、布爾值、null值或者是undefined。

當函數被調用的時候會產生一套新的變數,這允許遞迴的調用。

閉合

函數可以被定義到其他函數中,內建函式有權使用在外部函數定義的變數,如果一個引用內建函式繼續存在(例如一個回呼函數),那麼外部函數的變數也將繼續存在。

傳回值

JavaScript沒有void類型,所以每個函數都必須返回一個值,除了構造器之外預設值是undefined,構造器的預設傳回值是this

語句

語句包括 var, if, switch, for, while, do, break, continue, return, try, throw, and with,它們大多數與C類的語言相同。

var語句是一個或多個變數名稱的列表,它們以逗號隔開,帶著可選的初始設定式。

var a, b = window.document.body;

如果var語句出現在所有的函數之外那麼就聲明了一個全域的變數。如果出現在一個函數內,就聲明了一個局部的變數。

在if語句,while語句,do語句, 和符合邏輯的操作符中,JavaScript視為false,null,undefined, ""(Null 字元串),和數字0作為假(false)。其它所有值被視為真(true)。

在switch語句中的case標記可以是運算式,它們不必非得是常數,也可以是字串。

有2種形式的for語句,第一種像這樣 (init; test; inc)形式。第二種是對象重複器。

for (name in object) {    if (object.hasOwnProperty(name)) {        value = object[name];    }}

上面執行在object中的每一個name,名字產生的次序是不確定的。

語句可以有個首碼,就是一個標識符跟著一個冒號。

with語句不應該被使用

操作符

JavaScript有還算完整的操作符,大多數他們都與C類的語言工作的方式相同,但請注意一些細微的差異

+操作符用於加法和字串聯,如果任意運算元是字串,那麼進行串聯,這可能會引起錯誤,比如說'$' + 3 + 4 會得到'$34',而不是'$7'。

+可以作為一個首碼操作符把字元運算元轉化為數字。

!!可以作為一個首碼操作符,轉化運算元為布爾值。

&&操作符,一般被稱為“邏輯與”(logical and),它也被稱為guard,如果第一個運算元是false、null、undefined、""(Null 字元串)或者數字0那麼將返回第一個運算元,否則將返回第二個運算元。這提供了一個便利地測試null值的方法:

var value = p && p.name; /* The name value willonly be retrieved from p if p has a value, avoiding an error. */

||操作符一般被稱為“邏輯或”(logical or),它也被稱為default,如果第一個運算元是false、null、undefined、""(Null 字元串)或者數字0, 那麼將返回第二個運算元,否則返回第一個運算元。這提供了一個便利地設定預設值的方式:

value = v || 10; /* Use the value of v, but if vdoesn't have a value, use 10 instead. */

JavaScript支援一套逐位和移位的操作運算子,但卻沒有偶提供整型將他們應用。當一個數字運算元(一個64位浮點數)轉化成32位整型的在運算之前,然後在轉化回浮點數在操作在運算之後會發生什麼呢?

在JavaScript中,void是一個首碼操作符,而不是一種類型,它總是返回undefined值。這僅僅有一點點價值,我提到它的原因是萬一你不小心以習慣打出來它,而不會被它怪異的行為所迷惑。

typeof操作符返回一個基於它的運算元的字串

錯誤產生了。

Object 'object'
Array 'object'
Function 'function'
String 'string'
Number 'number'
Boolean 'boolean'
null 'object'
undefined 'undefined'
雜目全域對象

全域對象包含著所有的函數和所有的那些不在任何函數內定義的變數和對象,令人驚訝的是,全域變數在語言中並沒有一個確切的名字。一些時候,this指向它,但大多數情況並不是的。在瀏覽器中window和self都是指向全域對象的全域對象成員,因此給了一個間接的對它的定址方法。

如果一個變數可以被訪問,但是沒有在當前域下被找到,就會在全域物件範圍尋找,如果仍沒有,就會返回錯誤。

ECMAScript規範沒有談論關於多個全域對象的可行性,或者上下文關係,但是瀏覽器支援這個,每個視窗都有它自己的全域對象。

分號的插入時機

這個語言的一個錯誤及時分號的插入,有一個技巧是用分號來終止語句。用各種開發工具去進行插入工作是合理的,沒有必要為了語言的定義而讓編譯器去去做,請使用分號。

預留字

JavaScript對系統預留字的支援嚴重的過了頭,這些預留字是:

abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface
long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with

很大一部分這些關鍵字並沒有在JavaScript中使用,一個預留字不可以在如下的方式下被使用:

  1. 作為一個對象名字標記
  2. 作為點形式的的成員
  3. 作為函數的參數
  4. 作為一個var
  5. 作為一個絕對的全域變數
  6. 作為一個語句標號(As a statement label)

前2個限制是不可原諒的,絕對不要使用。接下來的2個的使用可以被接受,但是這樣使用是非常不牢靠的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.