javascript设计模式【02】继承

原型对象与prototype属性的区别

  1. 每个对象都有原型对象
  2. 只有函数才有prototype属性,当函数作为构造函数调用时,其prototype属性作为创建的对象的原型对象

实现继承的常用方法:

1    类继承:extend函数,将父类从子类构造函数中解耦,父类构造函数只要能恰当处理适当参数即可,通过superclass可以在需要重新定义父类方法是访问父类中的实现方法

  1.  1 function extend (subClass, superClass) {
     2   var F = function () {};
     3   F.prototype = superClass.prototype;
     4   subClass.prototype = new F();
     5   subClass.prototype.constructor = subClass;
     6   
     7   subClass.superclass = superClass.prototype; // 为子类定义静态属性,指明父类,实现解耦
     8   if (superClass.prototype.constructor === Object.prototype.constructor) {
     9     superClass.prototype.constructor = superClass;
    10   } // end if
    11 } // end extend()
    12 
    13 function Person (name) {
    14   this.name = name;
    15 } // end Person()
    16 Person.prototype.getName = function () {
    17   return this.name;
    18 }; // end getName()
    19 
    20 function Author (name, books) {
    21   Author.superclass.constructor.call(this, name); // 此时只要父类构造函数接受并正确处理name即可
    22   this.books = books;
    23 } // end Author()
    24 
    25 extend(Author, Person);
    26 
    27 Author.prototype.getBooks = function () {
    28   return this.books;
    29 }; // end getBooks()
    30 Author.prototype.getName = function () {
    31   // 通过superclass可以在需要重新定义父类方法是访问父类中的实现方法
    32   var name = Author.superclass.getName.call(this);
    33   return name + " , author of " + this.getBooks();
    34 }; // end getName()
    35 
    36 var a = new Author("xxx", "xxx");
    37 console.log(a.getName()); // xxx , author of xxx 

2    原型继承:通过clone创建子类。子类对象读写的不对等性:子类在为父类同名属性赋值之前引用的是父类属性,进行赋值时创建自己的属性,当父类包含引用类型时,如array.push()和object写操作。将影响父类,此时如果其他子类没有定义自己的对应属性,将会受到影响。

 1 function clone(obj) {
 2   function F () {};
 3   F.prototype = obj;
 4   return new F;
 5 } // end clone()
 6 
 7 var o = {
 8   name: "xxx",
 9   books: ["javascript"],
10   getName: function () {
11     return this.name;
12   }
13 };
14 
15 var b = clone(o);
16 console.log(b.getName()); // xxx
17 console.log(b.books); // ["javascript"]
18 
19 var c = clone(o);
20 console.log(c.hasOwnProperty("name")); // false
21 c.name = "ccc";
22 console.log(c.hasOwnProperty("name")); // true
23 console.log(c.name); // ccc 
24 c.books.push("java");
25 
26 console.log(b.getName()); // xxx
27 console.log(b.books); // ["javascript", "java"]

3    掺元类继承:将方法扩充的方式让类具有某个方法

 1 var Mixin = function () {};
 2 Mixin.prototype = {
 3   serialize: function () {
 4     var output = [];
 5     for (key in this) {
 6       output.push(key + ": " + this[key]);
 7     } // end for
 8     return output.join(", ");
 9   } // end serialize()
10 }; // end prototype
11 
12 function augment(receivingclass, givingClass) {
13   for (key in givingClass.prototype) {
14     if (!receivingClass.prototype[key]) {
15       receivingClass.prototype[key] = givingClass.prototype[key];
16     } // end if
17   } // end for
18 } // end augment()
19 
20 augment(Author, Mixin);
21 var author = new Author("xxx", "xxx");
22 var serializedString = author.serialize();

三种方式都可以实现继承。类式继承法与其他编程语言相似,容易理解。但是系统开销相对大。原型式继承为javascript所特有。简洁高效。掺元法类似接口实现。也不错,掺元法在提供通用方法时比较恰当。

原文地址:https://www.cnblogs.com/qiudeqing/p/3441923.html