js面向对象之:创建对象

最近在学习《js高级程序设计》,之前所接触的很多的js类库和jQuery插件都会用面向对象的方式来设计,而自己却还是停留在面向方法的阶段,所以今天好好记录一下学习的js创建对象。

 

第一种方式:工厂模式

function createPerson(name,age,job){

    var o = new Object();

    o.name = name;

    o.age = age;

    o.job = job;

    o.sayName = function(){

        alert(this.name);   

    };

    return o;   

}



//调用

var person = createPerson('张三',23,'IT');

person.sayName();

第二种方式:构造函数模式

function Person(name,age,job){

    this.name = name;

    this.age = age;

    this.job = job;

    this.sayName = function(){

        alert(this.name);   

    };

}



var person = new Person('李四',24,'nothing');
var person2 = new Person('李四2',22,'nothing');
alert(person.sayName == person2.sayName);//false

这种方式创建的对象实例,每一个实例都对应不同的name、age、job属性和sayName方法。

例如上面输出了两个实例的sayName方法是不同的对象。

 

第三种方式:原型模式

function Person(){

}



Person.prototype.name = '王五';

Person.prototype.age = 25;

Person.prototype.job = 'nothing';

Person.prototype.sayName = function(){

    alert(this.name);

};

也可改进为:

function Person(){ }
Person.prototype = {
name : '王五',
age : 25,
job : 'nothing',
sayName : function(){ alert(this.name); }

}
var person = new Person();

通过原型创建的属性,则在每一个实例之间共享,有点类似于static的感觉了。

原型的prototype会有一个默认创建的属性:constructor,指向创建prototype的函数的指针,拿前面的例子讲就是Person函数。

但是改进后的写法会有不同,Person.prototype.constructor不在指向Person函数了,因为下面的写法等于重写了Prototype为一个Object对象。

alert(person instanceof Person);//true

alert(person instanceof Object);//true

alert(person.constructor == Person);//false

alert(person.constructor == Object);//true

 

如果constructor属性很重要,可以手动指定。

function Person(){ } 

Person.prototype = {

    constructor : Person,

    name : '王五', 

    age : 25,

    job : 'nothing', 

    sayName : function(){ alert(this.name); }

}



var person = new Person();

 

 

 

在实际开发中,可以使用构造函数模式和原型混合编程

function Person(name,age){

    this.name = name;

    this.age = age;

}



Person.prototype = {

    custructor:Person,

    sayHi:function(){

        alert('Hi');

    }

};

这样既可以让实例拥有自己的属性(name、age),也可以有共享属性(sayHi方法)。

 

var person1 = new Person();



var person2 = new Person();



当person1实例重新定义name时,person1实例的name会改变,而原型中的name值保持不变



person1.name='王八蛋';



alert(person1.name); //王八蛋



alert(person2.name); //王五



//但是使用delete可删除实例属性,重新访问原型的属性

delete person1.name;

alert(person1.name);//王五

//hasOwnProperty可以检测实例是否有该属性,继承自Object
alert(person1.hasOwnProperty("name"));//false
 
   
//in可以检测是否有该属性,不论是实例属性还是原型属性
alert("name" in person1);//true
 

你可能感兴趣的:(面向对象)