面向对象编程
面向对象的基本方式JavaScript是一种面向对象的编程语言,其基本标志就是类(class)的概念,如图所示,可以通过类创建一系列有相同属性和方法的对象。
对于JavaScript,创建对象一般有四种模式:
-构造函数
-工厂模式
-原型模式
-动态原型模式
工厂模式
最简单直接,构造一个函数,在函数内部创建一个空对象,标出各项参数,然后在创建对象的时候直接将单个对象对应的参数进行输入。(可以想象成在一个工厂,内部创造框架,然后根据个体再来个性化配置)
例子如下:
var peopleFactory = function(name,age,state){
var temp = {};
temp.age = age;
temp.name = name;
temp.state = state;
temp.printPerson = function(){
console.log(this.name + ',' + this.age + ',' +this.state);
};
return temp;
};
var person1 = peopleFactory('john',23,'CA');
var person2 = peopleFactory('kim',27,'SA');
工厂模式的好处在于,他解决了实例化对象大量重复创建的问题,但他的缺点在于,无法进行对象识别(指的是,无法表示出实例跟原型的关系,比如实例中使用temp对象创建后来的person等,但这样创建出来的结果,person并没有原型,可以说是量产没有生产厂家)。
alert(person1 instanceof Object); //true
alert(person1 instanceof peopleFactory);//false
person1是Object,但没办法体现寄生关系,而寄生关系的体现一般需要new函数来实现。
构造函数模式
使用构造函数的方法,用构造函数本身作为框架,构建对象时需要将单个对象的属性分别装配,可以理解为,出厂一个带场标的车架,再根据你的个人需求配置属性。
var peopleConstructor = function(name,age,state){
this.age = age;
this.name = name;
this.state = state;
this.printPerson = function(){
console.log(this.name + ',' + this.age + ',' +this.state);
};
};
var person1 = new peopleConstructor('john',23,'CA');
var person2 = new peopleConstructor('kim',27,'SC');
person1.printPerson();
person2.printPerson();
运用new的方法创建函数的同时,也为函数添加了寄生关系,即:
peopleConstructor作为构造函数,person1,person2分别为这个构造函数的两个实例。
在这种时候,对实例进行对象检测:
alert(person1 instanceof Object); //true
alert(person1 instanceof peopleConstructor);//true
可以证明构造函数模式可以成功的进行对象识别。
但是,构造函数的问题在于,每次创建一个新的实例,不仅是语句,连构造函数内部的方法都要全部重新执行一遍,这样在处理大量数据的时候会明显的降低效率。
并且注意,此时不同实例的同名方法,并没有任何关系:
person1.printPerson == person2.printPerson; //false
原型模式
这种模式里,当我们使用构造函数创建新对象时,它所有的属性都被直接添加到了这个对象实例的原型里。同时,所有的方法也都被添加在了原型里,新的对象实例就不需要
当实例的某项属性不存在时,他此项属性的属性值将会从其原型中继承。
var peopleProto = function(){
};
peopleProto.prototype.age = 0;
peopleProto.prototype.name = 'no name';
peopleProto.prototype.city = 'no city';
peopleProto.prototype.printPerson = function(){
console.log(this.name + ',' + this.age + ',' + this.city);
};
var person1 = new peopleProto();
person1.name = 'john';
person1.age = 23;
person1.city = 'CA';
person1.printPerson();
但是必须注意一些特殊点:
在不给person1单独赋予某项属性时,他会从原型中继承,显示时也会直接显示此默认值。
然而当使用hasOwnProperty属性时,会报false。
表示此属性并非person1独有,而是继承自原型。
原型模式的问题则在于,你要提前建立一个空对象,且创建新对象时不能一步到位把各项属性输入,而是要一个一个单独进行。 为了解决这个问题,我们提出了动态原型模式。
动态原型
var peopleDynamicProto = function(name,age,state){
this.age = age;
this.name = name;
this.state = state;
if(typeof this.printPerson !== 'function'){
peopleDynamicProto.prototype.printPerson = function(){
console.log(this.name + ',' + this.age + ',' + this.state);
};
}
};
var person1 = new peopleDynamicProto('john',23,'CA');
person1.printPerson();
这样,将普通属性全部用构造函数方法添加,即能批量产生又能体现继承关系。对于函数方法则使用原型模式添加,这样就可以使实例的方法属性直接从其原型中继承。
网友评论