面向对象的编程(三)—封装

   三 直接继承prototype

    第三种方法是对第二种方法的改进。因为在Program对象中,不变的属性都可以直接写入Program.prototype中。我们可以让Book跳过Program(),直接继承Program.prototype。

 1 function Program(){}
 2 Program.prototype.task = '编程';
 3  function Book(name,color){
 4      this.name = name;
 5      this.color = color;
 6  }
 7  Book.prototype = Program.prototype;
 8  Book.prototype.constructor = Book;
 9  var book1 = new Book('JavaScript','黄色');
10  alert(book1.task);//输出:编程

将Book的prototype对象,然后指向Program的prototype对象,这样就完成了继承。

与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。缺点是 Book.prototype和Program.prototype现在指向了同一个对象,那么任何对Book.prototype的修改,都会反映到Program.prototype。

所以,上面这一段代码其实是有问题的:

1 Book.prototype.constructor = Book;

这个实际也把Program.prototype对象的constructor属性也改掉了

输出:

四 利用空对象作为中介

 由于"直接继承prototype"存在上述的缺点,所以就有第四种方法,利用一个空对象作为中介。

 

F是空对象,所以几乎不占内存。这时,修改Book的prototype对象,就不会影响到Program的prototype对象。

在这里,我们直接封装为一个extend函数,完整的例子,如下:

 1 function Program(){    }
 2 Program.prototype.task = '编程';//这里只能使用prototype属性
 3 
 4  function Book(name,color){
 5      this.name = name;
 6      this.color = color;
 7  }
 8  extend(Book,Program);
 9  var book1 = new Book('JavaScript','黄色');
10  alert(book1.task);
11  function extend(child,parent){
12      var F = function(){};
13      F.prototype = parent.prototype;
14      child.prototype = new F();
15     child.prototype.constructor = child;
16     child.uber = parent.prototype;
17  }

 Child.uber = Parent.prototype;

    最后一行意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。(uber是一个德语词,意思是"向上"、"上一层"。)这等于在子对象上打开一条通道,可以直接调用父对象的方法。这一行放在这里,只是为了实现继承的完备性,纯属备用性质。

 五 拷贝继承

上面我们使用的都是prototype属性,我们也可以换一种思路,纯粹采用"拷贝"方法实现继承。简单说,如果把父对象的所有属性和方法,拷贝进子对象,不也能够实现继承吗?这样我们就有了第五种方法。

   这里,program的属性不变,都放在prototype上:

然后,再写一个函数,实现属性拷贝的目的:

1  function extend(child,parent){
2      var p = parent.prototype;
3      var c = child.prototype;
4      for(var i in p){
5          c[i] = p[i];
6      }
7      c.uber = p;
8  }

这个函数的作用,就是将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象。

 完整的结构如下:

输出:

 

原文地址:https://www.cnblogs.com/xuzhudong/p/6538278.html