1. 程式人生 > >面向對象回顧

面向對象回顧

中一 表示 其中 情況下 繼承 script5 doc .proto 函數定義

/*
面向對象的程序設計
面向對象(Object-Oriented,OO)語言有一個標誌,那就是它們度要類的概念,而通過類可以創建任意多個具有相同屬性和方法的對象。
1理解對象
創建自定對象最簡單的方式就是創建一個Object的實例,然後再為它添加屬性和方法
*/
//對象字面量的方法
var person = new Object();
person.name = "Nicholas";
person.age = 29;
person.job = "Software Engineer";
person.sayName = function(){
alert(this.name);
}
var person = {
name:"Nicholas",
age:29,
job:"Software Engineer",
sayName:function(){
alert(this.name);
}
}
數據屬性
要修改默認屬性的特性,必須使用ECMAScript5的Object.defineProperty()方法。這個方法接受三個參數:屬性所在的對象,屬性的名字和一個描述符對象。其中描述符對象的屬性必須是configurable,enumerable,writable,value。設置其中一或多個值,可以修改對應的特性值
configurable: 表示能否通過delete刪除屬性從新定義屬性,能否修改屬性的特性,能否把屬性修改為訪問器屬性。
var person = {};
Object,defineProperty(person,"name",{
writable: false,
value: "Nicholas"
})
alert(person.name); //"Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"
訪問器屬性
訪問器屬性不包含數據值;他們包含一對兒getter和setter函數,在讀取訪問器屬性時,會調用getter函數,這個函數負責返回有效的值;在寫入訪問器屬性時,會調用setter函數傳入新值,這個函數負責決定如何處理數據。
訪問器屬性不能直接定義,必須使用Object。defineProperty()來定義。
var book = {
_year: 2004,
edition: 1
};
Object.defineProperty(book,"year",{
get:function(){
return this._year;
},
set:function(newValue){
if(newValue > 2004){
this._year = newValue;
this.edition += newValue -2004;
}
}
});
book.year = 2005;

創建對象
雖然Object構造函數或字面量可以用來創建單個對象,但這些方式有個明顯的缺點:使用同一個接口創建很多對象會產生大量的重復代碼。未解決這個問題,人們開始使用工廠模式的一種變體。
工廠模式
用函數來封裝特定接口創建對象的細節
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPreson("Nicholas",29,"Software Engineer");
var person2 = createPerson("Greg",27,"Doctor");
構造函數模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
}
}
var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Nicholas",29,"Greg",27,"Doctor");
創建Person的新實例,必須使用new操作符
(1)創建一個新對象
(2)將構造函數的作用域賦給新對象(因此this就指向了這個新對象)
(3)執行構造函數中的代碼(為這個心對象添加屬性)
(4)返回新對象
原型模式
我們創建的每個函數度有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。
function Person(){

}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "software enginner";
Person.peototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName();
理解原型對象
只要創建一個新函數,就會根據一組特定的規則為該函數創建一個prototype屬性,這個屬性指向函數的原型對象。
在默認的情況下,所有原型對象都會自動獲得一個constructor(構造函數)屬性,這個屬性包括一個指向prototype屬性所在函數的指針。
Person.prototype.constructor指向Person。而通過這個構造函數,我們可以為原型對象添加其他屬性和方法

hasOwnProperty()方法可以檢測一個屬性是否存在於實例中,還是存在原型中。
取得對象上所有可枚舉的實例屬性 Object.keys()方法,這個方法接受一個對象作為參數,返回包含所有可枚舉屬性的字符串數組:
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "software enginner";
Person.peototype.sayName = function(){
alert(this.name);
};
var keys = Object.keys(Person.prototype);
console.log(keys) ; //"nam,age,job,sayName"

組合使用構造函數模式和原型模式
創建自定義類型的最常見方式,就是組合使用構造函數模式與原型模式。
1構造函數模式用於定義實例屬性
2原型模式用於定義方法和共享屬性
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends = ["Shelby","count"];
}
Person.prototype={
constructor:Person,
sayName: function(){
console.log(this.name);
}
}
var person1 = new Person("Nicholas",29,"software engineer");
var person2 = new Person("Greg",19,"doctor");
Person1.friends.push("Van");
實例屬性都是在構造函數中定義,而所有實例共享的屬性constructor和方法都市在原型中定義
構造函數定義實例屬性,原型模式定義方法和共享屬性這種混合模式,比較廣泛

繼承 ECMAScript只支持實現繼承,而且主要依靠原型鏈繼承
每個構造函數度有一個原型對象,原型對象度包含一個指向構造函數的指針,實例包含一個指向原型對象的內部指針。假如一個原型有事另一個類型的實例這樣層層遞進構成實例和原型的鏈條。
function SuperType(){
this.prototype=true;
}
SuperType.prototype.getsuperValue = function(){
return this.prototype;
}
function SubType(){
this.subproperty = false;
}
//繼承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue =function(){
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());

組合繼承
function SuperType(name){
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
}
function SubType(name,age){
//繼承屬性
SuperType.call(this,name);
this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new SubType("Nick",29);
instance1.colors.push("black");
console.log(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //Nick
instance1.sayAge()//29

面向對象回顧