JavaScript Object Basic--http://www.josephjiang.com/presentation/OOJS/object-basic.html


傳統的物件導向語言不容易撰寫,像 VB.NET, C#, JAVA。如物件的撰寫必須放在另外的檔案(*.vb, *.cs)、必須使用 Class 這個關鍵字、不能用很簡單的方式去新增物件或指定物件。而 JavaScript 有上述物件導向語言的特性。不一樣的是,它的物件導向非常容易使用( Objects are soft ),可以使用很簡單的方法去新增子物件 ( Simple Assignment )。

由於 JavaScript 物件導向的撰寫模式很有彈性,對於物件階層你可以採用不同的寫法與想法 ( No Deep hierachies, Use Shallow Hierachies)

JavaScript - 世界上被誤解最深的程式語言

Douglas Crockford 在 The JavaScript Programming Language 提到 JavaScript,是世界上被誤解最深的程式語言,被誤解的原因如下:

  • The Name

    許多人會將 JavaScript 當成是 Java 的子程式、也有人會因為 script 這個字眼,而認為它不是一個真正的程式語言。

  • Moving Target

    第一版的 JavaScript 非常的粗糙,沒有例外處理、內部函式、以及繼承的概念。到現在的版本已經是一個物件導向的程式語言。即使如此,因為之前的粗糙,讓許多人有既定的印象。

    ECMA 組織不斷地在擴張 JavaScript 的功能性及完整性,原意是好的。但是就是版本太多,容易讓人產生混淆。

  • Design Errors

    JavaScript 跟其他語言一樣,有許多設計上的錯誤,例如 + 號同時代表了字串的串接及數值的相加、或者是 with 的使用、Regular Expression 的寫法、保留字的使用太過嚴格,這些設計上的錯誤都讓人在開發過程中產生疑惑。但是 ECMA 組織似乎沒有要修正這些問題的意思。

  • Bad Implementations

    因為早期的撰寫方式的不正確、為此語言帶來錯誤的影響。首頁建置百寶箱

  • Amateurs

    業餘愛好者,通常喜歡撰寫 JavaScript 的人都是不具有程式語言背景的,寫出來的東西自然就給人奇差無比的觀感。

  • Bad Books

    書籍或文件觀念不正確

  • Substandard Standard

    不夠標準的標準,The official specification for the language is published by ECMA. The specification is of extremely poor quality. It is difficult to read and very difficult to understand. This has been a contributor to the Bad Book problem because authors have been unable to use the standard document to improve their own understanding of the language. ECMA and the TC39 committee should be deeply embarrassed.

回到最上層

JavaScript 物件的特性

  • 沒有 Class (類別),但可以使用 Class 的概念

  • 物件中包含了一個或多個 Name-Value 所配對的子物件
  • Name 可以是任何的 String、Value 則可以是除了 undefined 以外的任何「值」
  • 可以以點運算子 ( dot notation ) 的方式存取一個物件底下的任何子物件,也可以以索引值、索引名稱的方式存取
回到最上層

JavaScript 物件的類型

Types

JavaScript 是由 Object 所組成。Array 是物件、Function 是物件、Objects 是物件。

在 JavaScript 的原生資料型態 (Primitive Data Type) 中,只有下列五種類型的「」( Value ) 不被視為物件:

  • Numbers ( 數值 )
  • Strings ( 字串值 )
  • Booleans ( 布林值 )
  • null ( 空值 )
  • undefined ( 未定義值 )

其它的所有東西,都算是物件的一種

回到最上層

開始使用物件

宣告與新增物件

1 varoObject=newObject();
2 //上一段有提到「字串值」不算是物件的一種,但這邊所宣告的是字串物件,不要混淆了喔!
3 varoStringObject=newString();
view plain | print | copy to clipboard | ?

在沒有參數使用時,可以將括號給拿掉。

摧毀 / 不再參考物件

1 varoObject=newObject();
2 ...
3 //最後要設為null
4 oObject=null;
view plain | print | copy to clipboard | ?

現今瀏覽器的 Script Engine 都有配備 Garbage Collector 的機制,當不再使用時,就會把物件參考回收。上述的範例是一個良好的習慣、實例中比較少看到。

回到最上層

Array

陣列的介紹

如前面所述的,陣列也是物件的一種,我們可以把陣列想像成是「物件的特別型態」。

前面提到物件可以用 Dot Notation 的方式存取、也可以用索引的方式存取。但是對於陣列而言,僅能使用索引的方式存取。

存取 Object

1 varoCar=newObject();
2 oCar.brand='Ford';
3 oCar.model='Focus';
4 varsModel=oCar.model;
view plain | print | copy to clipboard | ?

存取 Array

1 varaCar=newArray();
2 aCar['brand']='Ford';
3 aCar[1]='Focus';
4 varsModel=aCar['brand'];
view plain | print | copy to clipboard | ?

在沒有參數使用時,可以將括號給拿掉。

使用陣列的方式

最單純的宣告方式:

1 varaValue=newArray();
view plain | print | copy to clipboard | ?

你也可以帶一個參數,代表陣列的長度

1 varaValue=newArray(20)
view plain | print | copy to clipboard | ?

一個個指定值

1 varaColor=newArray();
2 aColor[0]='red';
3 aColor[1]='green';
4 aColor[2]='blue';
view plain | print | copy to clipboard | ?

在宣告時直接帶參數

1 varaColor=newArray('red','green','blue');
2 alert(aColor[1]);//輸出'green'
view plain | print | copy to clipboard | ?

.length 屬性、求取陣列的總長度

1 varaColor=newArray('red','green','blue');
2 alert(aColor.length);//輸出3
view plain | print | copy to clipboard | ?

宣告也可以直接使用中括號

1 varaColor=['red','green','blue'];
2 alert(aColor.length);//輸出3
3 aColor[25]='purple';
4 alert(aColor.length);//輸出26
view plain | print | copy to clipboard | ?

join() 方法合併為字串

1 varaColor=['red','green','blue'];
2 alert(aColor.join('&&'));//輸出red&&green&&blue
view plain | print | copy to clipboard | ?

push() 方法,新增一個 array item, 類似碗盤堆疊的概念

1 varaColor=[];
2 aColor.push('red');
3 aColor.push('green');
4 aColor.push('yellow');
5 alert(aColor.join(','));//輸出red,green,yellow
6 varsItem=aColor.pop();
7 alert(sItem);//輸出yellow
8 alert(aColor.join(','));//輸出red,green
view plain | print | copy to clipboard | ?

pop() 方法,會把最後一個 Array Item 移除

1 varaColor=['red','green','yellow'];
2 varsItem=aColor.pop();
3 alert(sItem);//輸出yellow
4 alert(aColor.join(','));//輸出red,green
view plain | print | copy to clipboard | ?

shift() 方法, 跟 Perl 一樣把第一個 Item 從陣列中抽出來

1 varaColor=['red','green','yellow'];
2 varsItem=aColor.shift();
3 alert(sItem);//輸出red
4 alert(aColor.join(','));//輸出green,yellow
view plain | print | copy to clipboard | ?

unshift() 方法, 則是塞 Item 到第一個

1 varaColor=['red','green','yellow'];
2 aColor.unshift('black');
3 alert(aColor.join(','));//輸出black,red,green,yellow
view plain | print | copy to clipboard | ?

sort() 跟 reverse() 指是替陣列做個排序

1 varaColor=['red','black','green','yellow'];
2 aColor.sort();
3 alert(aColor.join(','));//輸出black,green,red,yellow
4 aColor.reverse();
5 alert(aColor.join(','));//輸出yellow,red,green,black
view plain | print | copy to clipboard | ?
回到最上層

Scope

Scope 的介紹

任何一種程式語言都有 Scope 的概念, 代表的是某塊特定區域只能存取特定的變數

sort() 跟 reverse() 指是替陣列做個排序

1 varsMessage='Hello';
2
3 functionsetSomething(){
4 varsColor='red';
5 sMessage='HelloWorld!';
6 }
7
8 setSomething();
9
10 alert(sMessage);//輸出?
11 alert(sColor);//輸出?
view plain | print | copy to clipboard | ?

原始碼中共有 sMessage 及 sColor 兩個變數, 在整個 Js 的 Scope 中可存取到 sMessage 這個變數, 但是無法存取到 setSomething 函式裡面的 sColor, 因為 Scope 不相同

this 關鍵字

this 永遠都是指呼叫 function 的那個 object

1 varoCar=newObject;
2 oCar.color='red';
3 oCar.showColor=function(){
4 alert(this.color)
5 }
view plain | print | copy to clipboard | ?

這邊的 this 指的就是 oCar 物件

回到最上層

Public / Private / Priviledged Members

Public Member

在物件的階層中 ( 如 Object.ChildObject.GrandChildObject ),所有的成員都是 Public Members,所有其它的 Function 可以針對這些 Member 做存取、修改、刪除, 或者是新增成員。

Object Literal

1 //假設本來就有People.Joseph這個物件
2 varoJoseph=People.Joseph;
3 //即使本來沒有weight,height的屬性也可以去assign=>PublicVariables
4 oJoseph.weight=72;
5 oJoseph.height=178;
6 //當然可以去新增方法=>PublicMethod
7 oJoseph.cry=function(){
8 alert('嗚~Producer欺負我!');
9 };
view plain | print | copy to clipboard | ?

Function Literal

在 JavaScript 中可以把 Function 當成是物件導向語言中的 Class 或 Component,所以 Function 就是我們的 Constructor

1 //Constructor建構式
2 functionCar(sBrand,sModel,sPrice,sYear){
3 this.brand=sParam;
4 this.model=sModel;
5 this.price=sPrice;
6 this.year=sYear;
7 };
8
9 //在之後建立的物件都會有newMethod這個方法
10 Car.prototype.newMethod=function(){
11 //dosomethinghere
12 };
13
14 //利用Car這個Constructor建立一個新物件:在記憶體中新增一個區塊
15 varoCar=newCar('Ford','Focus','629000','2006');
16 //所以我們可以針對這個新物件去取得,oCar.model即是一個PuclicMember
17 alert(oCar.model);//output'focus'
18 //也可以去寫入
19 oCar.model='Activa';
20 alert(oCar.model);//output'Activa'
21 //也可以去刪除
22 oCar.price=null;
23 //還可以新增方法
24 oCar.init=function(){
25 alert('新車出廠');
26 }
view plain | print | copy to clipboard | ?

Private Members

如果你不希望 Class / Constructor 的屬性或方法被存取,只要不要用 this 的關鍵字即可

1 //Constructor建構式
2 functionCar(sBrand,sModel,sPrice,sYear){
3 //brand,model,price,year都是publicmember
4 this.brand=sParam;
5 //brand及oldMethod不會被外界給存取,就是privatemember
6 varbrand='BMW';
7 varoldMethod=function(){
8 //dosomethinghere...
9 };
10 };
view plain | print | copy to clipboard | ?

關於 var 宣告

在 JavaScript 宣告變數是 Loose Type 的,可以不用 var 就新增一個變數。

但如果不使用 var,就會讓這個新增的變數變成全域變數。

1 functionhello(msg){
2 //沒有使用var這個關鍵字做宣告
3 sMessage=msg;
4 };
5 //執行...
6 hello('helloworld');
7 alert(sMessage);//output'helloworld'
view plain | print | copy to clipboard | ?

我們並沒有在全域宣告 sMessage 這個變數,但是我們有在 function 內用到 sMessage 這個變數,由於沒有用 var 做宣告,以致於 sMessage 變成全域的變數,在執行 hello() 方法之後,sMessage 這個全域變數也產生了,所以接下來的 alert(sMessage) 才會有東西。

上面的例子讓變數的控制變得很困難,請一律在新增變數時加上 var,以避免問題。

1 functionhello(msg){
2 //這次我們加上了var關鍵字
3 varsMessage=msg;
4 };
5 hello('helloworld');
6 alert(sMessage);//outputundefined
view plain | print | copy to clipboard | ?
回到最上層

Closures

Closure 表示內部 Function 可以存取其外部的變數、參數、與方法,Closure 是 JavaScript 非常重要的一個特色。

1 //Constructor建構式
2 functionCar(sBrand,sModel,sPrice,sYear){
3 this.brand=sParam;
4 //外部宣告了brand
5 varbrand='BMW';
6 //內部函式oldMethod
7 varoldMethod=function(){
8 //幸虧有Closure,可以取得外部brand的值
9 alert(brand);//output'BMW'
10 //小心地使用this,最好連用都不用!
11 alert(this.brand);//output?
12 };
13 };
优质内容筛选与推荐>>
1、WebGIS--基于Internet的地理信息系统
2、平面划分空间问题
3、python操作excel实用脚本
4、ASP.NET状态管理 APPlication,Session,Cookie和ViewStat用法
5、从Controller注解切入了解spring注解原理


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn