javascript對象基礎之對象創建

摘自http://libinwalan.iteye.com/blog/153344

 

關鍵字: javascript對象, 面向對象

看js高級程序一書,記錄對自己比較重要的。

面嚮對象語言的要求:
1.封裝 2.聚集 3.繼承 4.多態
1.在Javascript中 可以創建並且使用的對象有三種
(1)本地對象 比如:Array Date and so on。
(2)內置對象 比如:Global Math(每個內置對象都是本地對象)
(3)宿主對象 定義:所有非本地對象都是宿主對象。所以所有的BOM(瀏覽器對象模型)和DOM(文檔對象模型)都是宿主對象。

2.作用域
(1)關鍵字this:總是指向調用該方法的對象 例如:

Js代碼 複製代碼
  1. var oCar = new Object;   
  2. oCar.color="red";   
  3. oCar .showColor = function(){   
  4. alert(this.color);//outputs "red"   
  5. };   
  6. //在上面的環境中 this等於car,下面的代碼與上面的代碼意義相同   
  7. var oCar = new Object;   
  8. oCar.color="red";   
  9. oCar .showColor = function(){   
  10. alert(oCar.color);//outputs "red"   
  11. };  
var oCar = new Object;
oCar.color="red";
oCar .showColor = function(){
alert(this.color);//outputs "red"
};
//在上面的環境中 this等於car,下面的代碼與上面的代碼意義相同
var oCar = new Object;
oCar.color="red";
oCar .showColor = function(){
alert(oCar.color);//outputs "red"
};

 使用this的好處是:可以在任意多個地方重用同一個函數。

3.定義類或對象

(1)工廠方式:考慮下面的代碼

Js代碼 複製代碼
  1. <script type="text/javascript">   
  2. function createCar(color, doors, mpg) {   
  3.     var tempcar = new Object;   
  4.     tempcar.color = color;   
  5.     tempcar.doors = doors;   
  6.     tempcar.mpg = mpg;   
  7.     tempcar.showColor = function () {   
  8.         alert(this.color)   
  9.     };   
  10.   
  11.     return tempcar;   
  12. }   
  13.   
  14. var car1 = createCar("red", 4, 23);   
  15. var car2 = createCar("blue", 3, 25);   
  16. car1.showColor();    //outputs "red"   
  17. car2.showColor();    //outputs "blue"   
  18.   
  19.   
  20. </script>  
<script type="text/javascript">
function createCar(color, doors, mpg) {
    var tempcar = new Object;
    tempcar.color = color;
    tempcar.doors = doors;
    tempcar.mpg = mpg;
    tempcar.showColor = function () {
        alert(this.color)
    };

    return tempcar;
}

var car1 = createCar("red", 4, 23);
var car2 = createCar("blue", 3, 25);
car1.showColor();    //outputs "red"
car2.showColor();    //outputs "blue"


</script>

 代碼夠清楚吧 不用多說了,但是要看清楚上面的代碼產生的問題:每次調用函數createCar(),都要創建新函數showColor();這意味着每個對象都有自己的showColor()版本,而事實上每個對象都共享了同一個函數。

所有這些問題引發了構造函數方式的出現:考慮下面代碼

Js代碼 複製代碼
  1. <script type="text/javascript">   
  2. function Car(sColor, iDoors, iMpg) {   
  3.     this.color = sColor;   
  4.     this.doors = iDoors;   
  5.     this.mpg = iMpg;   
  6.     this.showColor = function () {   
  7.         alert(this.color)   
  8.     };   
  9. }   
  10.   
  11. var oCar1 = new Car("red", 4, 23);   
  12. var oCar2 = new Car("blue", 3, 25);   
  13. oCar1.showColor();    //outputs "red"   
  14. oCar2.showColor();    //outputs "blue"   
  15.   
  16.   
  17. </script>  
<script type="text/javascript">
function Car(sColor, iDoors, iMpg) {
    this.color = sColor;
    this.doors = iDoors;
    this.mpg = iMpg;
    this.showColor = function () {
        alert(this.color)
    };
}

var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.showColor();    //outputs "red"
oCar2.showColor();    //outputs "blue"


</script>

你可能已經注意到差別了,在構造函數內部無創建對象,而是使用this關鍵字。現在就更像創建一般對象了。但是可惜它的缺陷和工廠函數的缺陷一樣。

(2)原型方式:即利用prototype屬性

首先讓我們看下面的例子:

Js代碼 複製代碼
  1. <script type="text/javascript">   
  2. function Car() {   
  3. }   
  4.   
  5. Car.prototype.color = "red";   
  6. Car.prototype.doors = 4;   
  7. Car.prototype.mpg = 23;   
  8. Car.prototype.showColor = function () {   
  9.     alert(this.color);   
  10. };   
  11.   
  12. var oCar1 = new Car();   
  13. var oCar2 = new Car();   
  14.   
  15. </script>  
<script type="text/javascript">
function Car() {
}

Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.showColor = function () {
    alert(this.color);
};

var oCar1 = new Car();
var oCar2 = new Car();

</script>

在上面的代碼中,通過給Car的pototype屬性添加屬性去定義Car對象的屬性。從語義上講,所有的屬性看起來都屬於一個對象,從而解決了前面方式存在的問題。但是遺憾的是它並不盡如人意。爲什麼呢?考慮下面的例子

Js代碼 複製代碼
  1. <script type="text/javascript">   
  2. function Car() {   
  3. }   
  4.   
  5. Car.prototype.color = "red";   
  6. Car.prototype.doors = 4;   
  7. Car.prototype.mpg = 23;   
  8. Car.prototype.drivers = new Array("Mike""Sue");   
  9. Car.prototype.showColor = function () {   
  10.     alert(this.color);   
  11. };   
  12.   
  13. var oCar1 = new Car();   
  14. var oCar2 = new Car();   
  15.   
  16. oCar1.drivers.push("Matt");   
  17.   
  18. alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"   
  19. alert(oCar2.drivers);    //outputs "Mike,Sue,Matt"   
  20.   
  21.   
  22. </script>  
<script type="text/javascript">
function Car() {
}

Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.drivers = new Array("Mike", "Sue");
Car.prototype.showColor = function () {
    alert(this.color);
};

var oCar1 = new Car();
var oCar2 = new Car();

oCar1.drivers.push("Matt");

alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"
alert(oCar2.drivers);    //outputs "Mike,Sue,Matt"


</script>

看到了吧 這是因爲Car的兩個實例都指向同一個數組。所以輸出都一樣了。

那麼是否有一種合理的創建對象的方法呢?答案是需要聯合使用構造函數和原型方試  考慮下面的列子

Js代碼 複製代碼
  1. <script type="text/javascript">   
  2. function Car(sColor, iDoors, iMpg) {   
  3.     this.color = sColor;   
  4.     this.doors = iDoors;   
  5.     this.mpg = iMpg;   
  6.     this.drivers = new Array("Mike""Sue");   
  7. }   
  8.   
  9. Car.prototype.showColor = function () {   
  10.     alert(this.color);   
  11. };   
  12.   
  13. var oCar1 = new Car("red", 4, 23);   
  14. var oCar2 = new Car("blue", 3, 25);   
  15.   
  16. oCar1.drivers.push("Matt");   
  17.   
  18. alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"   
  19. alert(oCar2.drivers);    //outputs "Mike,Sue"   
  20.   
  21. </script>  
<script type="text/javascript">
function Car(sColor, iDoors, iMpg) {
    this.color = sColor;
    this.doors = iDoors;
    this.mpg = iMpg;
    this.drivers = new Array("Mike", "Sue");
}

Car.prototype.showColor = function () {
    alert(this.color);
};

var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);

oCar1.drivers.push("Matt");

alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"
alert(oCar2.drivers);    //outputs "Mike,Sue"

</script>
 根據上面講述的內容 不難看出這種方式創建對象就更像創建一般對象了。這纔是最優的

(3)其他方法 

包括動態原型法(和上面最優的方式其實差不多,不做介紹了) 和混合工廠方式(不推薦,不做介紹了)

4.採用哪種方式:不用多說 當然是最優的拉,給個例子。運行下就知道效率了

Js代碼 複製代碼
  1. <script type="text/javascript">   
  2. function StringBuffer() {   
  3.     this.__strings__ = new Array;   
  4. }   
  5.   
  6. StringBuffer.prototype.append = function (str) {   
  7.     this.__strings__.push(str);   
  8. };   
  9.   
  10. StringBuffer.prototype.toString = function () {   
  11.     return this.__strings__.join("");   
  12. };   
  13.   
  14. var d1 = new Date();   
  15. var str = "";   
  16. for (var i=0; i < 10000; i++) {   
  17.     str += "text";   
  18. }   
  19. var d2 = new Date();   
  20.   
  21. document.write("Concatenation with plus: " + (d2.getTime() - d1.getTime()) + " milliseconds");   
  22.   
  23. var buffer = new StringBuffer();   
  24. d1 = new Date();   
  25. for (var i=0; i < 10000; i++) {   
  26.     buffer.append("text");   
  27. }   
  28. var result = buffer.toString();   
  29. d2 = new Date();   
  30.   
  31. document.write("<br />Concatenation with StringBuffer: " + (d2.getTime() -   
<script type="text/javascript">
function StringBuffer() {
    this.__strings__ = new Array;
}

StringBuffer.prototype.append = function (str) {
    this.__strings__.push(str);
};

StringBuffer.prototype.toString = function () {
    return this.__strings__.join("");
};

var d1 = new Date();
var str = "";
for (var i=0; i < 10000; i++) {
    str += "text";
}
var d2 = new Date();

document.write("Concatenation with plus: " + (d2.getTime() - d1.getTime()) + " milliseconds");

var buffer = new StringBuffer();
d1 = new Date();
for (var i=0; i < 10000; i++) {
    buffer.append("text");
}
var result = buffer.toString();
d2 = new Date();

document.write("<br />Concatenation with StringBuffer: " + (d2.getTime() - 
Js代碼 複製代碼
  1. d1.getTime()) + " milliseconds");   
  2.   
  3. </script>  
d1.getTime()) + " milliseconds");

</script>
 這段代碼對字符串鏈接進行2個測試,第一個使用加號,第二個使用StringBuffer類。事實證明後者比前者節省大量的時間。COOL! OVER!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章