js对象定义
JS中的对象定义方式,跟服务端,还是有很大差别的!
现在来说一下JS类的定义
工厂模式
function creatHeven(name,age){
var temp =new Object();
temp.age=age;
temp.name=name;
temp.say=function(){
alert(this.name);
};
return temp;
}
var tempHeaven=creatHeaven('heaven','29');
大家可以看到工厂模式很简单,但是也有一些问题,它虽然解决了具有一些共性类的创建,但是我们无法知道当前创建的类是什么具体类型,只能知道是一个Object,例如不能知道 Date等;
为了解决这个问题,于是就有了构造函数模式创建类;
构造函数模式:
function CreatHeaven(name,age){
this.name=name;
this.age=age;
this.say=function(){
alert(this.name);
};
}
var tempHeaven=new CreatHeaven('heaven',30);
大家看到,一些定义方式做了改变,类名称首字母也大写了,没有return,使用了new关键字;也能识别对象;
构造函数虽然好用,但是也是有缺点的,使用构造函数模式最大的缺点就是每次创建对象,都要创建方法,造成资源浪费,因此,我们可以将方法移到类外面,定义一个全局函数,但是这样看来并不像是一个类对象。
例如:
function say(){
alert(this.name);
};
function CreatHeaven(name,age){
this.name=name;
this.age=age;
this.say=say;
};
}
var tempHeaven=new CreatHeaven('heaven',30);
这样做,显然失去了面向对象封装的意义,我们可以采用原型模式去创建一个对象;
原型模式:
我们创建的每个函数都有prototype原型属性,这个属相是一个指针,它指向一个对象;而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法
function CreatHeaven(name,age){
CreatHeaven.prototype.name=name;
CreatHeaven.prototype.age=age;
CreatHeaven.prototype.say=function(){
alert(this.name);
};
}
var tempHeaven1=new CreatHeaven('heaven1',30);
var tempHeaven2=new CreatHeaven('heaven2',30);
原型模式也有缺点,就是如果属性是一个对象,例如数组;这样在创建实例的时候,就是公用这个数组,数组内容改变了,其他实例都是指向这个数组,值也会跟着变。这是我们不想要的结果。
所以出现了,”原型模式+构造函数模式“ 的方式创建类实例;
原型模式+构造函数模式:
function CreatHeaven(name,age){
this.name=name;
thsi.age=age;
}
CreatHeaven.prototype.say=function(){
alert(this.name);
};
var tempHeaven1=new CreatHeaven('heaven1',30);
tempHeaven1.say();
var tempHeaven2=new CreatHeaven('heaven2',30);
tempHeaven2.say()
每个实例都会有自己的一份实例属性,但同时又共享着方法,最大限度的节省了内存。另外这种模式还支持传递初始参数。优点甚多。这种模式在ECMAScript中是使用最广泛、认同度最高的一种创建自定义对象的方法。
动态原型模式:
unction CreatHeaven(name,age){
this.name=name;
this.age=age;
if(typeof this.say!='function'){
CreatHeaven.prototype.say=function(){
alert(this.name);
};
}
}
var tempHeaven1=new CreatHeaven('heaven1',30);
tempHeaven1.say();
var tempHeaven2=new CreatHeaven('heaven2',30);
tempHeaven2.say()
动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型(仅第一个对象实例化时初始化原型),这个可以通过判断该方法是否有效而选择是否需要初始化原型。
总结:以上就是几个创建类实例的模式,根据具体需要选择哪个创建模式;推荐使用 ”原型模式+构造函数模式“,”动态原型模式“。