[轉載]javascript建立物件的幾種方式

candy-yun發表於2016-06-23

原文連結:http://qingfeng825.iteye.com/blog/1935648

1. 工廠方法:能建立並返回特定型別物件的工廠函式(factory function).

function createCar(sColor) {
    // 或者 var car = new Object;
    var car = new Object();
    // 物件屬性
    car.color = sColor;
    // 物件方法
    car.showColor = function() {
        alert(123);
    };
    // 記住,這裡一定要用;表示結束

    // 這裡是 return car;而不是 return this.car;因為 this.car 為 undefined
    return car;
}

// 呼叫此函式時,將建立物件,並賦予它所有必要的屬性,使用此方法建立car物件的兩個版本(oCar1和oCar2),他們的屬性完全一樣。
// 使用此方法存在的問題:
// 1.語義上看起來不像使用帶有建構函式的new運算那麼正規.
// 2.使用這種方式必須建立物件的方法。每次呼叫createCar(),都要建立showColor(),
// 意味著每一個物件都有自己的showColor版本,事實上,每一個物件都共享了是同一個函式.
// 有些開發者在工廠函式外定義物件的方法,然後通過屬性指向該方法。從而避免這個問題:

function createCar2(sColor) {
    var car = new Object();
    car.color = sColor;
    car.showColor = showColor;
    return car;
}

function showColor() {
    alert(this.color);
}

var oCar1 = createCar(`red`);
var oCar2 = createCar(`yellow`);
var oCar3 = createCar2(`blue`);
var oCar4 = createCar2(`black`);
// 注意這兩個物件(oCar3 和 oCar4)呼叫showColor 屬性的方式,雖然美其名曰是“屬性”,其實還是方法!!!
// 所以是oCar3.showColor();而不是 oCar3.showColor;
oCar3.showColor();
oCar4.showColor();

// 在這段重寫的程式碼中,在函式createCar2()前定義了函式showColor(),
// 在createCar2()內部,賦予物件一個已經指向已經存在的showColor()函式的指標,
// 從功能上講,這樣解決了重複建立物件的問題,但該函式看起來不像物件的方法。
// 所有這些問題引起了開發者的定義建構函式的出現


2. 建構函式方式

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

var car1 = new Car(`red`);
car1.showColor();

// 你可能已經注意到第一個的差別了,在建構函式內部無建立物件,而是使用this關鍵字,
// 使用new運算子呼叫建構函式,在執行第一行程式碼前先建立一個物件,只有用this才能訪問該物件。
// 然後可以直接賦予this屬性,預設情況下是建構函式的返回值,(不必明確使用return運算子)。
// 這種方式在管理函式方面與工廠方法一樣都存在相同的問題.


3. 原型方式

function PCar() {
}

PCar.prototype.color = “blue”;
var pcar1 = new PCar();

// 呼叫newCar()時,原型的所有屬性都被立即賦予要建立的物件,意味著所有的PCar例項存放的是指向showColor()函式的指標,
// 從語義看起來都屬於一個物件,因此解決了前面兩種方式存在的問題。
// 此外使用該方法,還能使用instanceof運算子檢查給定變數指向的物件型別。

// 因此下面的程式碼將輸出true:
// output “true”
alert(pcar1 instanceof PCar);

// 這個方法看起來不錯,遺憾的是,它並不盡人意。
// 1.首先這個建構函式沒有引數。使用原型方式時,不能給建構函式傳遞引數初始化屬性值,因為pcar1和pcar2的屬性都等於”blue”
// 2.真正的問題出現在屬性指向的物件,而不是函式時,函式共享不會造成任何問題,但是物件卻是很少被多個例項共享的。


4. 混合的建構函式/原型方式(推薦)

// 聯合使用建構函式和原型方式,就可像使用其他程式設計語言一樣建立物件,
// 這種概念非常簡單,即用建構函式定義物件的所有非函式屬性,用原型方式定義物件的函式屬性(方法)。
function hCar(sColor) {
    this.color = sColor;
    this.drivers = new Array(`Mike`, `Sue`);
}

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

var hcar1 = new hCar(`y color`);
var hcar2 = new hCar(`r color`);

hcar1.drivers.push(`Matt`);

// output “Mike,Sue,Matt”
alert(hcar1.drivers);
// output “Mike,Sue”
alert(hcar2.drivers);


5. 動態原型方式(推薦)

// 對於習慣使用其他開發語言的開發者來說,使用混合建構函式/原型方式感覺不那麼和諧。
// 批評建構函式/原型方式的人認為,在建構函式內找屬性,在外部找方法的做法不合理。
// 所以他們設計了動態原型方式,以供更友好的編碼風格。
// 動態原型方式的基本想法與混合建構函式/原型方式相同,即在建構函式內定義非函式的屬性,
// 而函式的屬性則利用原型屬性定義。
// 唯一的區別是賦予物件方法的位置。
// 下面是使用動態原型方法重寫的Car類:
function DCar(sColor) {
    this.color = sColor;
    this.drivers = new Array(`Mike`, `Sue`);

    if (typeof DCar._initialized == `undefined`) {

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

    DCar._initialized = true;
}

var dcar1 = new DCar(`y dcar`);
var dcar2 = new DCar(`b dcar`);

dcar1.showColor();
dcar2.showColor();

// output “true”
alert(DCar._initialized);
// output “undefined”
alert(dcar1._initialized);


6、物件直接量、new建立

// 建立物件最簡單的方法是你的javascript程式碼中包含物件直接量,也可以通過運算子new建立。
var empty = {};// An object with no properties
var point = {
    x : 0,
    y : 0
};
var circle = {
    x : point.x,
    y : point.y + 1,
    radius : 2
};
var homer = {
    “name” : “Homer Simpson”,
    “age” : 34,
    “married” : true,
    “occupation” : “plant operator”,
    `email` : `homer@example.com`
};
// Create an empty array
var a = new Array();
// Create an object representing the current date and time
var d = new Date();
// Create a pattern-matching object
var r = new RegExp(“javascript”, “i”);
// 建立物件後,我們可以通過”.”運算子,在物件中建立新屬性、引用已有屬性、設定屬性值等。
// 建立物件
var book = new Object();
book.title = “JavaScript: The Definitive Guide”;

// 作為物件屬性的,巢狀物件
book.chapter1 = new Object();
book.chapter1.title = “Introduction to JavaScript”;
book.chapter1.pages = 11;
book.chapter2 = {
    title : “Lexical Structure”,
    pages : 6
};
// 從物件中讀取一些屬性.
alert(“Outline: ” + book.title + ”
” + “Chapter 1 ” + book.chapter1.title
        + ”
” + “Chapter 2 ” + book.chapter2.title);
// 在上例中,需注意,可以通過把一個值賦給物件的一個新屬性來建立它.
// 在JavaScript語句中提到過用for/in語句可以遍歷物件的屬性和方法。
// 刪除屬性:
delete book.chapter2;

 

作者: Candyメ奶糖

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
博文來源廣泛,如原作者認為我侵犯智慧財產權,請儘快給我發郵件
359031282@qq.com聯絡,我將以第一時間刪除相關內容。


相關文章