好吧,我是个标题党,我只是想聊一聊对象创建~也就是我们常说的类,只是在ECMAScript中,只有对象,对象创建对象。
1.最基本的创建方式
直接创建对象,并设置属性方法~
var oPerson = new Object;
oPerson.name = "Pada";
oPerson.sex = "female";
oPerson.age = 22;
oPerson.say = function () { //say属性存放着函数的指针
alert(this.name);
};
缺点:需要创建多个实例,每个实例对应单一对象
2.工厂方式
封装对象,使其能能创建并返回特定类型的对象
function creatPerson(){
var oPerson = new Object;
oPerson.name = "Pada";
oPerson.sex = "female";
oPerson.age = 22;
oPerson.say = function () {
alert(this.name);
};
return oPerson;
}
var oPerson1 = creatPerson();
var oPerson2 = creatPerson();
但此时oPerson1,oPerson2 属性完全一样,介个感觉不太好,毕竟这个世界又不只有一个人,不然可就真的孤独了,我们可以利用函数传参来区分它们~
function creatPerson(sName,sSex,iAge){
var oPerson = new Object;
oPerson.name = sName;
oPerson.sex = sSex;
oPerson.age = iAge;
oPerson.say = function () {
alert(this.name);
};
return oPerson;
}
var oPerson1 = creatPerson("Pada",female,22);
var oPerson2 = creatPerson("Amy",female,23);
oPerson1.say(); //"Pada"
oPerson2.say(); //"Amy"
缺点:每次创建对象都会创建方法副本,但其实各对象方法是一样的,我们需要想办法共享它~
function say(){
alert(this.name);
}
function creatPerson(sName,sSex,iAge){
var oPerson = new Object;
oPerson.name = sName;
oPerson.sex = sSex;
oPerson.age = iAge;
oPerson.say = say; //这样,每次创建时只是创建了指向函数的指针,而非函数体
return oPerson;
}
var oPerson1 = creatPerson("Pada",female,22);
var oPerson2 = creatPerson("Amy",female,23);
oPerson1.say(); //"Pada"
oPerson2.say(); //"Amy"
3.混合工厂方式
仅仅只是在工厂方式的基础上构建假的构造函数,建议避免使用~
function Person(){
var oPerson = new Object;
oPerson.name = "Pada";
oPerson.sex = "female";
oPerson.age = 22;
oPerson.say = function () {
alert(this.name);
};
return oPerson;
}
var oPerson1 = new Person();
var oPerson2 = new Person();
4.构造函数方式
function creatPerson(sName,sSex,iAge){
this.name = sName;
this.sex = sSex;
this.age = iAge;
this.say = function () {
alert(this.name);
};
return oPerson;
}
var oPerson1 = new creatPerson("Pada",female,22);
var oPerson2 = new creatPerson("Amy",female,23);
oPerson1.say(); //"Pada"
oPerson2.say(); //"Amy"
缺点:构造函数也会重复生成函数,为每个对象创建独有的函数,该方法也可以先缓存函数,以提高性能~
5.原型方式
function Person(){}
Person.prototype.name = "Pada";
Person.prototype.sex = "female";
Person.prototype.age = 22;
Person.prototype.say = function(){
alert(this.name);
};
var oPenson1 = new Person();
var oPenson2 = new Person();
缺点:构造函数没有参数,实例间会相互影响
function Person(){}
Person.prototype.name = "Pada";
Person.prototype.sex = "female";
Person.prototype.age = 22;
Person.prototype.sport = new Array("basketball","dance"); //此时存放的是数组对象的指针
Person.prototype.say = function(){
alert(this.name);
};
var oPenson1 = new Person();
var oPenson2 = new Person();
oPerson1.sport.push("swin");
alert(oPerson1.sport); //"basketball,dance,swim"
alert(oPerson2.sport); //"basketball,dance,swim"
该解决的问题还是要解决滴,看下面~
6.混合的构造函数/原型方式
使用构造函数定义对象所有非函数属性,用原型方式定义对象函数(方法)
function Person(sName,sSex,iAge){
this.name = sName;
this.sex = sSex;
this.age = iAge;
this.sport = new Array("basketball","dance");
}
Person.prototype.say = function(){
alert(this.name);
};
var oPenson1 = new Person("Pada",female,22);
var oPenson2 = new Person("Amy",female,23);
oPerson1.sport.push("swin");
alert(oPerson1.sport); //"basketball,dance,swim"
alert(oPerson2.sport); //"basketball,dance"
优点:通过传参使得我们可以构建一般对象,只创建一个say()函数,节约了内存,oPerson1与oPerson2的sport设置互不影响,由于使用了原型方式,我们还可以通过instanceof运算符来判断对象的类型(是否基于某一般对象,或者说是否为某对象实例)
7.动态原型方法
function Person(sName,sSex,iAge){
this.name = sName;
this.sex = sSex;
this.age = iAge;
this.sport = new Array("basketball","dance");
if(typeof Person._initialized == "undefined"){ //判断say是否已经初始化定义了
Person.prototype.say = function(){
alert(this.name);
};
Person._initialized = true;
}
}