重温面向对象的几种模式与原型

本文探讨了面向对象编程中几种常用的设计模式,包括原始情况、工厂模式、构造函数模式及原型模式,并对比了它们的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每次当觉得自己对原型这里有点了解的时候就会出来一道题打脸,,,so决定再重新看一遍,

关于面向对象的几种模式及其优缺点

原始情况

var box = new Object();     //创建一个Object对象
box.name = 'Lee';       //创建属性
box.run = function () {     //创建一个run()方法
    return this.name + this.age;
};

缺点:创建类似的对象的话就要再写一遍代码,复用率不好

工厂模式

用来解决声明多个类似对象问题,提高代码复用率,大概就是写一个模板,用的时候传入具体值就可以了,以实现上面的功能为例

function createObject(name, age) {  
    var obj = new Object();
    obj.name = name;
    obj.age=age;
    obj.run = function () {
        return this.name + this.age;
    };
    return obj;
}
// 调用
var box1 = createObject('rose', 100);//第一个实例
var box2 = createObject('Jack', 200);//第二个实例
alert(box1.run());
alert(box2.run());                      //保持独立

缺点:这样写是不用重复的写好多代码,但是有一个问题。先假设还有一个createObject2,这个函数也返回一个对象,用他实例化一个box3,这时你完全搞不清楚box1、2、3到底谁是谁的对象,
所以就有构造函数这个模式

构造函数模式

function Box(name, age) {               //构造函数模式
    this.name = name;
    this.age=age;
    this.run = function () {
        return this.name + this.age;
    };
}

var box1 = new Box('Lee', 100); 
//很清晰的看到他是Box实例化来的
var box2 = new Box('Jack', 200);
alert(box1.run());
alert(box1 instanceof Box); 

优点:解决了重写重复代码的问题,解决了找自己对象的问题。可以看到他与前面所说的创建对象的方法的不同之处:

  1. 他没有创建对象(new Object());
  2. 直接将属性和方法赋值给当前对象(this);
  3. 也没有返回一个对象。
    没有上面这些他是怎么创建一个对象的呢:
  4. new 构造函数(),后台自动执行new Object();
  5. 实例化后构造函数的作用域给了实例,即this指向了实例;
  6. 执行构造函数内的代码;
  7. 后台自动返回新对象。

构造函数的规范:
1. 为了区分普通函数,首字母要大写,但是不强制,函数名和new的时候名字要相同
2. 通过new操作符实例化一个对象
上面的代码,虽然box1、box2都是同一个构造函数创建的,但是他们的方法是不相等的,每次实例化的时候相当于创建一个Function(new Function()),这样其实是没有必要的,有一个解决方法是把通用的方法写成全局的,这样每次实例化完属性后,再直接全局调用需要的方法,但是这样就没有封装性可言了,下面说的原型模式可以解决这个问题。

原型模式

原型 实现所有对象的实例共享对象的属性和方法,创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,简单粗暴的来说就是它包含对象的所有实例需要共享的属性和方法。

function Box() {}   //声明一个构造函数

Box.prototype.name = 'Lee'; //在原型里添加属性          
Box.prototype.run = function () {//在原型里添加方法
    return this.name + this.age;
};
// 实例化
var box1 = new Box();
var box2 = new Box();
alert(box1.run == box2.run);//true,每个实例对对象原型的方法的调用其实是引用,不会每实例化一次就创建一次

感觉原型里面比较混乱的就是下面这些内容了,先说一下有哪些然后再分别记录

  • prototype:函数属性,指向函数的原型对象;
  • 原型对象的constructor:包含一个指向prototype属性所在函数的指针,拿前面的例子来说Box.prototype.constructor = Box;
  • 内部属性[[Prototype]]__proto___:这是新实例包含的一个指针,指向构造函数的原型对象。挺纠结的,这两个叫法不是很兼容,所以只要记住有这么一个指针存在就好了;
  • isPrototypeOf:可以通过isPrototypeOf方法确定实例与原型对象是否存在上面说的那种关系Box.prototype.isPrototypeOf(box1),返回true;
  • Object.getPrototypeOf()[ES5] : 取得一个对象的原型对象。这个方法返回[[Prototype]]的值Object.getPrototypeOf(box1) == Box.prototype;

  • 这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值