面向对象程序设计
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"