1. 程式人生 > >js裡的面向物件分析-(建立例項化物件) 建構函式

js裡的面向物件分析-(建立例項化物件) 建構函式

ECMAScript 有兩種開發模式:1.函式式(過程化),2.面向物件(OOP)。面向物件的語言有一個標誌,那就是類的概念,而通過類可以建立任意多個具有相同屬性和方法的物件。但是,ECMAScript 沒有類的概念,因此它的物件也與基於類的語言中的物件有所不同。

js本身是沒有class型別的,但是每個函式都有一個prototype屬性。prototype指向一個物件,當函式作為建構函式時,prototype則起到類似class的作用。

複製程式碼

var box = new Object(); //建立一個Object 物件
box.name = 'Lee'; //建立一個name 屬性並賦值
box.age = 100; //建立一個age 屬性並賦值
box.run = function () { //建立一個run()方法並返回值
return this.name + this.age + '執行中...';
};
alert(box.run()); //輸出屬性和方法的值

複製程式碼

上面建立了一個物件,並且建立屬性和方法,並且例項化該物件,最後呼叫物件的方法。在run()方法裡的this,就是代表box 物件本身。但是有個缺點就是不能例項化多個具有相似屬性和方法的物件。於是我們想到了可不可以有一套模板來批量製作物件。於是就有了-工廠模式。看下面例子

複製程式碼

function createObject(name, age) { //集中例項化的函式
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function () {
return this.name + this.age + '執行中...';
};
return obj;
}
var box1 = createObject('Lee', 100); //第一個例項
var box2 = createObject('Jack', 200); //第二個例項
alert(box1.run());
alert(box2.run()); //保持獨立

複製程式碼

這種方法雖然製造出來了一套模板來規範待例項化的物件。但是還有許多問題,比如建立不同物件其中屬性和方法都會重複建立,消耗記憶體,還有函式識別問題等等。其實還有更優秀的也是用的最多的方法,看下面示例。

複製程式碼

function Box(name, age) { //建構函式模式
this.name = name;
this.age = age;
this.run = function () {
return this.name + this.age + '執行中...';
};
}
var box1 = new Box('Lee', 100); //new Box()即可
var box2 = new Box('Jack', 200);
alert(box1.run());
alert(box1 instanceof Box); //很清晰的識別他從屬於Box

複製程式碼

這個方法看似像一個函式,但又有些不太一樣。比如函式名一般都小寫。如果學過其他面向物件的語言就會知道,這是類的寫法(此處不多分析,非強制,但這麼寫有助於區分建構函式和 普通函式)。這種方法是建構函式建立物件的寫法,通過建構函式建立物件,必須使用new 運算子。

建構函式可以建立物件執行的過程:

1)當使用了建構函式,並且new 建構函式(),那麼就後臺執行了new Object(); 2)將建構函式的作用域給新物件,(即new Object()創建出的物件),而函式體內的this 就 代表new Object()出來的物件。 3)執行建構函式內的程式碼; 4)返回新物件(後臺直接返回)。

注:

1)建構函式和普通函式的唯一區別,就是他們呼叫的方式不同。只不過,建構函式也是函式,必須用new 運算子來呼叫,否則就是普通函式。

2)this就是代表當前作用域物件的引用。如果在全域性範圍this 就代表window 物件,如果在建構函式體內,就代表當前的建構函式所宣告的物件。

這種方法解決了函式識別問題,但消耗記憶體問題沒有解決。同時又帶來了一個新的問題,全域性中的this 在物件呼叫的時候是Box 本身,而當作普通函式呼叫的時候,this 又代表window。即this作用域的問題。