在
06
年用
javascript
寫過上千行的應用,現在的項目中經常用到
javascript
,說不熟悉吧也熟悉了。說熟悉吧,
javascript
的面向對象部分還是比較陌生。實際上自己沒有系統學習過
javascript
,沒有完整看過一本
javascript
的書。今天決定網上定兩本書,一本是《
javascript
高級程序設計》《
javascript dom
編程藝術》,想著也該較系統的學習一下,項目中也要大量應用到這些了,必定下一個項目我們將采用
AJAX
。總結下自己學
ajax
時候補充的一點
javascript
知識。
一、
javascript
面向對象特性
1.
javascript
中的函數
javascript
的
function
對象在調用過程中具有一個
arguments
屬性,它是由腳本解釋器創建的,這也是創建
arguments
唯一途徑。
Arguments
對象可以看作是一個
Array
對象,它具有
length
屬性,可以通過序號訪問每一個參數。
Arguments
有個
callee
屬性,可以獲取到執行的
function
對象的引用。
eg
:
funtion f1
(
n
)
{
if(n<=0)
{
return 1;
}else
{
return n*arguments.callee(n-1);//
實際同
return n*f1(n-1);
}
上例利用
callee
屬性實現了匿名的遞歸調用。
2.
apply
和
call
方法:
apply
方法和
call
方法有形似之處,兩者都將函數綁定到其他對象上執行。
舉例:
obj1.fun1.apply(obj2,[“test”]);
含義:是將
obj1
對象的方法
fun1
綁定到
對象
obj2
上,并使用參數
test
。
obj1.fun1.call(obj2,“test”);
含義同上,他們區別是在
apply
參數以
array
對象傳入。而
call
是依次傳入參數的。
3.
this
和
with
this
在對象的方法被調用時候,指代調用該方法的對象實例。
使用
with
語句時,代碼變得更加短且易讀:
沒有用
with
之前
x = obj.fun1(“a”);
y = obj.fun2(“b”);
用
with
之后,就變成:
with(obj)
{
x=fun1(“a”);
y=fun2(“b”);
}
4.
for in
在
javascript
中可以使用
for in
語句遍歷對象中所有屬性和方法。例如下面的代碼就遍歷了
test1
對象的屬性和方法,如果是屬性則輸出屬性值,如果是方法則執行方法。
for(p in t)
{
if(typeof(t[p])==”function”)
{
t[p]();
}else
{
alert(t[p]);
}
}
二、
javascript
面向對象編程實現
對比
java
中面向對象編程中繼承,以及封裝,多態等常見概念,進行總結。
1.
類的聲明
首先來看下類的實現,前面已經使用了一種聲明類的方法。
function test1()
{
this.prop1 = “prop
this.prop2 =”prop
this.fun1 = function()
{
……
}
}
上面代碼聲明了兩個公有屬性,和一個方法。大家都知道類里除了公有成員還可能還有一些私有成員變量,但是
javascript
并沒有提供相應的機制來定義私有成員變量,不過利用一些
javascript
的小技巧就可以實現私有成員變量。如下:
function test1 ()
{
var prop3 = “test”;
this.prop1 = “prop
this.prop2 =”prop
this.fun1 = function()
{
……
}
}
上面代碼通過
var
關鍵字聲明了一個局部變量
prop3
,其作用域是
test1
類定義的內部,這樣就實現了變量私有化。
另外在
javascript
中可以通過下面的方式聲明靜態屬性和靜態方法。
<
script
LANGUAGE
="
JavaScript
"
>
function
test
(
n
)
{
}
test
.
staticProp
=
" static prop test!"
;
test
.
staticMechod
=
function
()
{
alert
(
"adfadfd"
);
}
alert
(
test
.
staticProp
);
test
.
staticMechod
();
</
script
>
實際上沒有感覺到
javascript
中靜態的必要性(不像
java
),也許是我對書本理解的不夠,或者是應用太少。如果有讀者朋友,有不同認識,歡迎發表看法,大家交流。
如果要聲明一個類的實例屬性或方法,可以使用
javascript
中對象的
prototype
屬性。例如:
test1.prototype.prop1 = “prop
test1.prototype.method1 = function(){}
利用
prototype
屬性,可以實現另外一種類的聲明方式:
<
script
LANGUAGE
="
JavaScript
"
>
function
test
()
{}
test
.
prototype
=
{
p1
:
"p1"
,
p2
:
"p2"
,
f1
:
function
()
{
alert
(
"f1"
);
}
}
var
te
=
new
test
();
te
.
f1
();
</
script
>
上面使用
{}
的方式聲明了一個匿名對象,大括號內用逗號將屬性與值的列表分隔開。可以看到,采用
prototype
的方式聲明類,代碼更加簡潔明了。因此這種方式在很多
AJAX
框架中得到廣泛應用。
2.
繼承
javascript
本身并沒有提供繼承,那么如何實現類的繼承呢?最直接大方法是復制原方法,然后在里面加入新成員。但這樣做實在是落后,因為當原類變化,新繼承的類還要手動變化,容易出錯。而下面這種用
for in
控制的復制就不那么容易出錯了。
function test1()
{
for(p in test.prototype)
{
test1.prototype[p] = test.prototype[p];
}
test1.prototype.newmethod = function()
{
alert(“newfunction”);
}
}
3.
多態
多態的是實現可以采用和繼承類似的方法。首先定義一個抽象類,其中可以調用一些虛方法,虛方法在抽象類中沒有定義,而是通過其具體實現類來實現的。
<
script
LANGUAGE
="
JavaScript
"
>
//
一個繼承方法
Object
.
extend
=
function
(
destination
,
source
)
{
for
(
pro
in
source
)
{
destination
[
pro
]
=
source
[
pro
];
}
return
destination
;
}
//
一個基類
function
base
(){}
base
.
prototype
=
{
f1
:
function
()
{
this
.
oninit
();
}
}
//
擴展1
function
test1
()
{
}
test1
.
prototype
=
Object
.
extend
(
{
prop
:
"prop"
,
oninit
:
function
()
{
alert
(
this
.
prop
);
}
},
base
.
prototype
);
//
擴展2
function
test2
()
{
}
test2
.
prototype
=
Object
.
extend
(
{
prop2
:
"prop2"
,
oninit
:
function
()
{
alert
(
this
.
prop2
);
}
},
base
.
prototype
);
//
測試
var
t1
=
new
test1
();
t1
.
f1
();
var
t2
=
new
test2
();
t2
.
f1
();
</
script
>