代码复用

2018-04-11  本文已影响0人  李华炎

1.原型式继承

  1. 须知:每一个函数都有prototype属性
  2. 对象的构造函数可以从其他对象继承方法,它创建出一个原型对象后,其他所有的新对象都可以基于这个原型对象来构建。
  3. 原型继承的设计适用于单继承。
<script>
   function Person(name) {
       this.name = name;
   }
   Person.prototype.getName = function () {
       return this.name;
   }

   function User(name, password) {
       this.name = name;
       this.password = password;
   }
   User.prototype = new Person('coco');
   User.prototype.getPassword = function () {
       return this.password;
   }

   var u = new User('lili','123456');
   console.log(u.getName()); // 从原型上继承到的方法
   console.log(u.getPassword());
</script>

2.类式继承

  1. 继承自单一函数
  2. 从单一父对象继承所有内容
  3. 从多个父对象继承独立的方法
// 1.一个辅助的函数,将方法绑定到函数的原型上
// 继承自单一函数
Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
}

// 2.一个复杂的函数,允许从其他类中继承函数,并且还可以调用父类中的函数。
// 从单一父对象继承所有内容
Function.method('inherits',function (parent) {
    // 记录我们目前所在父层次的级数
    var depth = 0;

    // 继承父对象的方法
    var proto = this.prototype = new parent();

    // 创建一个新的名为uber 的 ‘特权’函数
    // 调用它时会执行所有在继承时被重写的函数
    this.method('uber',function (name) {
        var func; // 要执行的函数
        var ret;    // 函数的返回值
        var v = parent.prototype;   // 父对象的原型
        // 如果我们已经在某个uber函数之内
        if (depth){
            // 上溯必要的depth,以找到原始的prototype
            for (var i = depth; i > 0; i += 1) {
                v = v.constructor.prototype;
            }

            // 从该prototype中获得函数
            func = v[name];

            // 否则这就是 uber 函数的第一次调用
        }else {
            // 从原型获得要执行的函数
            func = proto[name];

            // 如果此函数属于当前的 prototype
            if (func == this[name]){
                // 则改为调用父对象的 prototype
                func = v[name];
            }
        }

        // 记录我们在继承堆栈中所在位置的级数
        depth += 1;

        // 使用除第一个以外所有的 arguments 调用此函数
        // 因为第一个参数是执行的函数名
        ret = func.apply(this,Array.prototype.slice.apply(arguments,[1]));
        // 恢复继承堆栈
        depth -= 1;

        // 返回执行过的函数的返回值
        return ret;
    });
    return this;
});


// 3.只继承父对象特定函数。而非使用 new parent() 继承所有的函数
// 从多个父对象继承独立的方法
Function.method('swiss',function (parent) {
    // 遍历所有要继承的方法
    for (var i = 1; i < arguments.length; i++) {
        // 需要导入的方法名
        var name = arguments[i];

        // 将parent的原型上的name方法赋值给 调用method方法的对象的原型
        this.prototype[name] = parent.prototype[name];
    }
    return this;
});


// 应用案例----------
function Person(name) {                 // 创建一个 Person 构造函数
    this.name = name;
}
Person.method('getName',function () {   // 给Person添加一个新的方法
    return this.name;
});

function User(name, password) {         // 创建一个 User 构造函数
    this.name = name;
    this.password = password;
}

User.inherits(Person);                  // 从 Person对象继承所有方法
User.method('getPassword',function () { // 给 User对象添加一个新方法
   return this.password;
});

// 覆盖继承 Person对象的getName方法,但可以通过uber方法调用原来的getName方法
User.method('getName',function () {
    return 'My name is '+ this.uber('getName');
});

var u = new User('冬瓜',22589);
console.log(u.getName());       // 冬瓜
console.log(u.getPassword());   // 22589

3.Base库

4.Prototype库

上一篇 下一篇

猜你喜欢

热点阅读