面向對象程序設計
1:創建對象
1:第一種方式,創建object的實例
//第一種方式,直接調用基類object創建
var Person = new Object();
Person.name = "daimeng";
Person.age = "21";
Person.getName = function(){
return this.name;
}
Person.setName = function(){
this.name = "qinjie";
}
alert(Person.name);
Person.setName();
alert(Person.getName());
2:對象字面量創建,目前較多使用
//第二種方式,對象字面量
var Person = {
name:"qinjie",
age:21,
getName:function(){
return this.name;
},
setName:function(){
this.name = "daimeng";
}
};
alert(Person.getName());
Person.setName();
alert(Person.name);
3:工廠模式,減少代碼量,定義了接口。但是不清楚相似對象的類型
function createPerson(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.getName =function(){
return o.name;
}
return o;
}
var p1 = createPerson("qinjie",21);
alert(p1.getName());
var p2 = createPerson("daimeng",21);
alert(p2.getName());
//依此,可以使用此接口創建很多類似的對象,無需重複定義
4:構造函數模式
function Person(name,age){
this.name = name;
this.age = age;
this.getName = function(){
return this.name;
};
}
var person = new Person("daimeng",21);
var person2 = new Person("qinjie",21);
alert(person.getName());
alert(person2.getName());
5:原型模式,成員變量中含有”引用類型”時,會導致數據共享。
function Person(){
}
Person.prototype.name = "qinjie";
Person.prototype.age = 21;
Person.prototype.getName = function(){
return this.name;
};
Person.prototype.game =['lol','cf'];
Person.prototype.setName = function(name){
this.name = name;
}
var p1 = new Person();
var p2 = new Person();
p2.setName("daimeng");
p2.game.push("dnf");
alert(p1.getName());
alert(p2.getName());
alert(p1.game);//lol,cf,dnf
alert(p2.game);//lol,cf,dnf 兩者數值一樣
6:原型模式和構造模式混合使用,最常見的一種方式,取衆長。
function Person(){
this.name = "qinjie";
this.age = 21;
this.game = ["lol","cf"];
}
Person.prototype.getName = function(){
return this.name;
}
Person.prototype.setName = function(name){
this.name = name;
}
var person1 = new Person();
var person2 = new Person();
person1.setName("daimeng");
person2.setName("dm");
person1.game.push("dnf");
alert(person1.getName()); //daimeng
alert(person1.game); //lol,cf,dnf
alert(person2.getName()); //dm
alert(person2.game); //lol,cf
7:還有一些其他的模式,動態原型模式,繼承構造函數模式,穩妥構造函數模式。。。哈哈,以後用的時候再總結吧
2:繼承
1:原型鏈繼承,會導致引用類型出錯(所有實例共用引用類型)。
function Base(){
this.name = "qinjie";
this.game = ["lol","cf"];
}
Base.prototype.getName = function(){
return this.name;
}
function Super(){
// Base.call(this);
}
Super.prototype = new Base();
Super.prototype.getGame = function(){
return this.game;
}
var sup1 = new Super();
var sup2 = new Super();
sup1.game.push("dnf");
alert(sup1.getName());//qinjie
alert(sup1.getGame());//lol,cf,dnf
alert(sup2.getGame());//lol,cf,dnf
2:引用構造函數,會導致無法使用原型模式構造的函數
function Base(){
this.name = "qinjie";
this.game = ["lol","cf"];
}
Base.prototype.getName = function(){
return this.name;
}
function Super(){
Base.call(this);
}
// Super.prototype = new Base();
Super.prototype.getGame = function(){
return this.game;
}
var sup1 = new Super();
var sup2 = new Super();
sup1.game.push("dnf");
alert(sup1.getName());//報錯,找不到該function
alert(sup1.getGame());
alert(sup2.getGame());
3:組合使用構造函數模式和原型模式
function Base(){
this.name = "qinjie";
this.game = ["lol","cf"];
}
Base.prototype.getName = function(){
return this.name;
}
function Super(){
Base.call(this);
}
Super.prototype = new Base();
Super.prototype.getGame = function(){
return this.game;
}
var sup1 = new Super();
var sup2 = new Super();
sup1.game.push("dnf");
alert(sup1.getName());//qinjie
alert(sup1.getGame());//lol,cf,dnf
alert(sup2.getGame());//lol,cf
3:屬性類型
1:在ECMA-262第五版中,描述了屬性的特徵。屬性可以用來設置變量和方法的行爲特徵。分爲:數據屬性和訪問器屬性。
數據屬性:[[Configurable]],[[Enumerable]],[[Writable]][[value]];
訪問器屬性:[[Configurable]],[[Enumerable]],[[Get]],[[Set]];
var Person = {};//定義多個屬性的值
Object.defineProperties(Person,{
_name:{//"_"表示name變量只能通過對象方法才能訪問的屬性
value:"daimeng"//定義數據屬性
},
age:{
value:21
},
name:{//定義訪問器屬性
get:function(){
return this._name;
},
set:function(name){
this._name = name;
}
}
});
alert(Person.name);
Person.name = "qinjie";
alert(Person.name);//在ie11和chrome最新瀏覽器值爲"daimeng"
2:使用Object.getOwnPropertyDesciptor()取得給定屬性的值
var book = {};
Object.defineProperties(book, {
_year: {
value: 2004
},
edition: {
value: 1
},
year: {
get: function(){
return this._year;
},
set: function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); //2004
alert(descriptor.configurable); //false
alert(typeof descriptor.get); //"undefined"
var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value); //undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get); //"function"