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

来源:互联网 发布:天蝎座为什么被黑 知乎 编辑:程序博客网 时间:2024/06/05 17:10

每次当觉得自己对原型这里有点了解的时候就会出来一道题打脸,,,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.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.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;

  • 这里写图片描述
阅读全文
0 0
原创粉丝点击