关于面向对象的几种模式和个人理解

关于面向对象的几种模式和个人理解。

  • 创建对象最初方式
//object构造函数:
var person = new object();
person.name = "lisi";
person.age = 25;
//字面量形式:
var person = {
    name:'lisi',
    age:25
}

缺点:使用同一个接口创建很多对象,会产生大量的重复代码。
为了解决这种问题,推出了工厂模式

  • 工厂模式
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 person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");

缺点:工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别问题(即怎么知道一个对象的类型)
于是,又推出了构造函数模式

  • 构造函数模式
function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

不同之处:

  • 没有显式创建对象;
  • 直接将属性和方法赋给了this对象;
  • 没有return语句

缺点:使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一次。并且不同函数上的同名函数是不相等的,以下代码证明这一点:

alert(person1.sayName == person2.sayName); //false

然而,创建两个完全相同任务的function实例的确没有必要,况且有this对象在,根本不用再执行代码前就把函数绑定到对象上面。因此,大家可以向下面这样,通过把函数定义转移到构造函数外部来解决这个问题

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}
function sayName(){
    alert(this.name);
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

这样确实解决了两个函数做同一件事的问题,但是新的问题又来了:在全局作用局下只为某个对象定义一个函数,这让全局作用域有点名副其实。而且更让人无法接受的是:如果对象需要定义很多的方法,那么就要定义很多的全局函数,于是,我们这个自定义的引用类型就毫无封装性可言了。
于是,又推出了原型模式

  • 原型模式
function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true

通过构造函数方式创建新对象,与构造函数不同的是,这些属性和方法都是可以共享的。


补充
更简单的原型语句:

function Person(){}
Person.prototype = {
    name : "Nicholas",
    age : 29,
    job: "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};

  • 最终版============》组合使用构造函数和原型模式
function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Shelby", "Court"];
}
Person.prototype = {
    constructor : Person,
    sayName : function(){
        alert(this.name);
    }
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

在这个实例中,实例属性都是构造函数中定义的,而由所有实例共享的属性constructor和方法sayName()则是在原型中定义的。而修改person1中的friends(向其中添加一个新的字符串),并不会影响到person2.friends,因为他们分别引用了不用的数组.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值