日期:2014-05-16  浏览次数:20417 次

js 面向对象学习6 几种面向对象写法的对比

方法一

var o=new Object();
o.age=20;
o.name="lisa";
o.showName=function(){
    console.log(this.name);
}

?这种写法创建了一个对象o 给o添加属性和方法,看似没有问题但是在创建多个o 就需要重复的给o添加属性,所以这种写法是较为不通用的一种写法,

方法二

?? 很多人想到干脆用工厂创建o 就可以解决o无法重复创建问题代码如下

function createPerson(age,name){
    var o=new Object();
    o.age=age;
    o.name=name;
    o.showName=function(){
        console.log(this.name);
    }
    return o;
?}

?这样解决了重复创建对象的问题,通过createPerson 这个工厂就可以创建多个不同的对象,每个都有不同age属性,不同name属性,但是showName在每个创建对象的时候也会穿件一个新的方法模板,是不是有点浪费内存

?

所有就有以下的改造方法把showName单独提取出来代码如下

function createPerson(age,name){
    var o=new Object();
    o.age=age;
    o.name=name;
    o.showName =showName;
    return o;
 }
function showName(){
     console.log(this.name);

}

如此这番的改造就解决showName方法多次创建的问题,也节约了内存,是不是很奇怪,感觉写习惯面向对象代码的人看着这些是不是非常不习惯的。

?

方法三

通过构造方法构建对象代码如下

function Person(age,name){
    this.age=age;
    this.name=name;
    this.showName=function(){
           console.log(this.age);
    }
}
var p1=new Person(12,"lisa");
var p2=new Person(15,"lee");

?观察以上代码区别,这个person 中是没有new Object() 和返回值的,所有Person 就是一个构造器,用来构造Person对象这种写法同样是没有解决showName多次创建的问题,解决方法也是跟上边是一样的只有提取出showName方法

?

方法四

?通过prototype属性构建对象代码如下

function Person(){}
Person.prototype.age=12;
Person.prototype.name="lee";
Person.prototype.pArray=new Array();
Person.prototype.showName=function(){
           console.log(this.name);
};

var p1=new Person();
p1.pArray.push("sa");
var p2=new Person();
console.log(p1.showName===p2.showName);//true
console.log(p1.pArray[0]);//sa
console.log(p2.pArray[0]);//sa
?
?

了解prototype属性就应该知道每个创建的person对象都会自动拥有age name 属性和showName 方法而且 这种写法有一个好处就是解决了showName重复创建的问题,但是两个新问题也随之而来,无法使用构造器传递参数,如Person(23,"sa"),更要命的是如果属性是引用类型的所有创建的对象都会持有同一个引用 所以就导致了 pArray 值都是一样,如何解决这个问题?

?

方法五

混合模式 prototype +构造器同时创建对象代码如下

function Perosn(age,name){
     this.age=age;
     this.name=name;
     this.array=new Array();
}
Person.prototype.showName=function(){
     console.log(this.name);
}

?如此这般就同时规避了以上的两个问题。而且可以用instanceof 得知对象。

方法六

?方法五其实已经没有硬伤了,但是开发者会感觉代码不够优美,所以就诞生了动态原型方法,代码如下

function Person(age,name){
       this.age=age;
       this.name=name;
       if(typeof Person._initialized=='undefined'){
             Person.prototype.showName=function(){
                     console.log(this.name);
             }
             Person._initialized=true;
        }
}
?

开发者经过大量的实践在js面向对象编程中发现的比较科学的方法。

?

?