美文网首页
2.第一篇:面向对象编程

2.第一篇:面向对象编程

作者: 爱吃鱼的肥兔子 | 来源:发表于2018-11-23 14:23 被阅读0次

    本文摘自 《JavaScript 设计模式》张容铭 著 版权归原作者所有

    第2章 写的都是看到的---面向对象编程

    2.2 封装

    2.2.1 创建一个类

    var book = function(id,bookname,price){
        this.id = id;
        this.bookname = name;
        this.price = price;
    }
    book.prototype.display = function(){
        //展示这本书
    }
    或者
    book.prototype = {
        display : function(){}
    }
    var book = new book(10,'一本书',50);
    console.log(book.name); // 一本书
    

    2.2.2 属性与方法封装

    
    //私有属性与私有方法,特权方法,对象公有属性和对象共有方法,构造器
    
    var Book = function(id,name,price){
        // 私有属性
        var num  = 1;
        // 私有方法
        function checkId(){};
        // 特权方法
        this.getName = function(){};
        this.getPrice = function(){};
        this.setName = function(){};
        this.setPrice = function(){};
        // 对象公有属性
        this.id = id;
        // 对象共有方法
        this.copy = function(){};
        // 构造器
        this.setName(name);
        this.setPrice(price);   
    }
    
    // 类静态公有属性(对象不能访问)
    Book.isCHinese = true;
    Book.resetTime = function(){
        console.log('new Time')
    }
    Book.prototype = {
        // 公有属性
        isJSBook : false,
        // 公有方法
        disPlay : function(){}
    }
    

    2.2.3 闭包实现

    有时我们经常将类的静态变量通过闭包来实现

    // 利用闭包实现
    var book = (function(){
      //  静态私有变量
      var bookNum = 0;
      // 静态私有方法
      function checkBook(name){  
      }
      //  返回构造函数
      return function(newId,newName,newPrice){
        // 私有变量
        var name,price;
        // 私有方法
        function checkID(id){
        }
        // 特权方法
        this,getName = function(){};
        this.getPrice = function(){};
        this.setName = function(){};
        this.setPrice = function(){};
        //   公有属性
        this.id = newId;
        // 公有方法
        this.copy = function(){};
        bookNum++
        if(bookNum > 100) throw new Error('超额出售了');
        // 构造器
        this.setName(name);
        this.setPrice(price);
      }
      _book.prototype = {
        isJSBook : false,
        display : function(){}
      }
      return _book;
    })();
    
    闭包是有权访问另外一个函数作用域中变量的函数,即在一个函数内部创建另外一个函数。
    

    2.2.4 创建对象的安全模式

    var book = function(title,name,type){
      // 判断执行过程中this是否是当前这个对象(如果是说明是new创建的)
      if(this instanceof Book){
        this.title = title;
        this.name = name;
        this.type = type; 
      }else{
        return new Book(title,name,type);
      }
    }
    var book = Book('JS36个设计模式','2014','js');
    
    console.log(book); // Book
    console.log(book.title);  // JS36个设计模式
    console.log(book.name);  // 2014
    console.log(book.type); // js
    console.log(window.title); // undefined
    console.log(window.name); // undefined
    console.log(window.type); // undefined
    

    2.3 继承

    2.3.1子类的原型对象——类式继承

    // 类式继承
    // 声明父类
    function SuperClass(){
      this.superValue = true;
    }
    // 为父类添加共有方法
    SuperClass.prototype.getSuperValue = function(){
      return this.superValue;
    }
    // 声明子类
    function SubClass(){
      this.SubValue = false;
    }
    // 继承父类
    SubClass.prototype = new SuperClass(); 
    SubClass.prototype .getSubValue = function(){
      return this.SubValue;
    }
    
    var instance = new SubClass();
    console.log(instance.superValue); // true
    console.log(instance.SubValue ); // false
    

    通过instanceof来检测某个对象是否是某个类的实例。

    console.log(instance instanceof SuperClass); // true
    console.log(instance instanceof SubClass); // true
    
    console.log(SubClass instanceof SuperClass); // false
    
    // instanceof 是判断前面的对象实收是后面类的实例,它并不表示两者的继承。
    继承父类时是将SuperClass 的实例赋值给SubClass的原型prototype,SubClass.prototype继承了SuperClass
    console.log(SubClass.prototype instanceof SuperClass); // true
    

    2.3.2 构造函数继承

    // 构造函数式继承
    // 声明父类
    function SuperClass(){
      // 引用类型共有属性
      this.books = ['Javascript','html','css'];
      // 值类型共有属性
      this.id = id;
    }
    // 父类声明原型方法
    SuperClass.prototype.showBook = function(){
      console.log(this.book);
    }
    // 声明子类
    function SubClass(id){
      // 继承父类
      // 由于call这个方法可以更改函数的作用环境,因此在子类中,对SuperClass调用这个方法就是将子类中的变量在父类中执行一遍,
      // 由于父类中是给this绑定属性的,因此子类自然也就继承了父类的共有属性。
      SuperClass.call(this,id);
    }
    // 创建第一个子类的实例
    var instance1 = new SubClass(10);
    // 创建第二个子类的实例
    var instance2 = new SubClass(11);
    instance1.books.push('设计模型');
    console.log(instance1.books); //  ['Javascript','html','css',‘设计模型’]
    console.log(instance1.id); // 10;
    console.log(insrance2.books); // ['Javascript','html','css']
    console.log(instance2.id); //11
    

    2.3.3 组合继承

    // 组合式继承
    // 声明父类
    function SuperClass(name){
      // 值类型共有属性
      this.name = name;
      // 引用类型共有属性
      this.books = ['html','css','js'];
    }
    // 父类原型共有方法
    SuperClass.prototype.getName = function(){
      console.log(this.name);
    }
    // 声明子类
    function SubClass(name,time){
      // 构造函数式继承父类name属性;
      SuperClass.call(this,name);
      this.time = time
    };
    // 类式继承 子类原型继承父类
    SubClass.prototype = new SuperClass();
    // 子类原型方法
    SubClass.prototype.getTime = function(){
      consoel.log(this.time);
    }
    var instance1 = new SubClass('js book','2014');
    instance1.books.push('设计模型');
    console.log(instance1.books);//  ['html','css','js','设计模型'];
    instance1.getName();// js book
    instance1.getTime(); // 2014
    
    var instance2 = new SubClass('css book','2015');
    console.log(instance2.books); //  ['html','css','js'];
    instance2.getName(); // css book
    instance3.getTime(); // 2015
    

    2.3.4 原型式继承

    // 原型式继承
    function inheritObject(o){
      // 声明一个过渡函数对象
      function F(){};
      // 过渡对象的原型继承父对象
      F.prototype = o;
      // 返回过渡对象的一个实例,该实例的原型继承了父对象
      return new F();
    }
    
    var book = {
      name:'js book';
      alikeBook:['css book','html book'];
    }
    var newBook = inheritObject(book);
    newBook.name = 'ajax book';
    newBook.alikeBook.push('xml book');
    
    var otherBook = inheritObject(book);
    otherBook.name = 'flash book';
    otherBook.alikeBook.push('as book');
    
    console.log(newBook.name); // ajax book
    console.log(newBook.alikeBook); // ['css book','html book','ajax book']
    
    console.log(otherBook.name); // flash book
    console.log(otherBook.alikeBook); // ['css book','html book','as book']
    
    console.log(book.name); // js book
    console.log(book.alikeBook);// ['css book','html book']
    

    2.3.5 寄生式继承

    // 寄生式继承
    // 声明基对象
    var book = {
      name:'js book',
      alikeBook:['css book','html book']
    };
    function createBook(obj){
      // 通过原型继承方式创建新对象
      var o = new inheritObjet(obj);
      // o.getName = function(){
       console.log(name);
      };
      // 返回拓展后的新对象
    return o;
    }
    

    2.3.6 寄生组合式继承

    /**
    * 寄生式继承 继承原型
    * 传递参数 subClass 子类
    * 传递参数 superClass 父类
    **/
    function inheritPrototype(subClass,superClass){
      // 复制一份父类的原型副本保存在变量中
      var p = inheritObject(superClass.prototype);
      // 修正因为重写子类原型导致子类的constructor属性被修改
      p.constructor = subClass;
      // 设置子类的原型
      subClass.prototype = p;
    }
    // 定义父类
    function SuperClass(name){
      this.name = name;
      this.colors = ['red','blue','green'];
    }
    // 定义父类原型方法
    SuperClass.prototype.getName = function(){
      console.log(this.name);
    }
    // 定义子类
    function SubClass(name,time){
      // 构造函数式继承
      SuperClass.call(this,name);
      // 子类新增属性
      this.time = time;
    }
    // 寄生式继承父类原型
    inheritPrototype(SubClass,SuperClass);
    // 子类新增原型方法
    SubClass.prototype.getTime = function(){
      console.log(this.time)
    }
    // 创建两个测试方法
    var instance1 = new SubClass('js book',2014);
    var instance2 = new SubClass('css book',2013);
    
    instance1.colors.push('black');
    console.log(instance1.colors);//  ['red','blue','green','black']
    console.log(instance2.colors);// ['red','blue','green']
    instance2.getName();// css book;
    instance2.getTime();// 2013
    

    2.4 多继承

    • 单继承实例
    // 单继承  属性复制
    var extend = function(target,source){
      // 遍历源对象中的属性
      for(var prototype in source){
        // 将源对象中的属性复制到目标对象中
        target[prototype] = source[prototype]
      }
      // 返回目标对象
      return target;
    }
    var book = {
      name:'JS设计模型',
      alike:['css','html','JS']
    }
    var anotherBook = {
      color:'blue'
    }
    extend(anotherBook.book);
    console.log(anotherBook.name); // JS设计模型
    console.log(anotherBook.alike);// ['css','html','JS']
    
    anotherBook.alike.push('ajax');
    another.name = '设计模式';
    console.log(another.name); // 设计模式
    console.log(another.alike); // ['css','html','JS','ajax']
    console.log(book.name); // JS设计模型
    console.log(book.alike); // ['css','html','JS','ajax']
    
    
    • 多继承实例
    // 多继承 属性复制
    var mix = function(){
      var i = 1, // 从第二个参数起为呗继承的对象
        len = arguments.length, //  获取参数长度
        target = arguments[0], // 第一个对象为目标对象
        arg; // 缓存参数对象
      // 遍历被继承的对象
      for(; i < len; i++){
        // 缓存当前对象
        arg = arguments[i];
        // 遍历被继承对象中的属性
        for(var prototype in arg){
          // 将被继承对象中的属性复制到目标对象中
          target[prototype] = arg[prototype];
        }
      }
       // 返回目标对象
       return target;
    }
    

    或者

    Object.prototype.mix = function(){
      var i = 0, // 从第一个参数起为被继承的对象
        len = arguments.length, //获取参数长度
        arg; // 缓存参数对象
      // 遍历被继承的对象
      for(; i < len; i++){
        // 缓存当前对象
        arg = arguments[i];
        // 遍历被继承对象中的属性
         for(var prototype in arg){
          // 将被继承对象中的属性复制到目标对象中
          target[prototype] = arg[prototype];
        }
      }
    }
    otherBook.mix(book1,book2);
    console.log(otherBook)
    

    2.5 多态

    //多态
    function Add(){
      // 无参数算法
      function zero(){
        return 10;
      }
      // 第一个参数算法
      function one(num){
         return 10+num; 
       }
      // 两个参数算法
      function two(num1,num2){
        return num1+num2;
      }
      // 相加共有方法
      this.add = function(){
        var arg = arguments,
        // 获取参数长度
        len = arg.length;
        switch(len){
          // 如果没有参数长度
          case 0:
            return zero();
          case 1:
            return one(arg[0]);
          case 2:
            return two(arg[0],arg[1])
        }
      }
    }
    // 实例化类
    var A = new Add();
    console.log(A.Add()); // 10;
    console.log(A.add(5)); // 15
    console.log(A.add(6,6)); // 12
    

    相关文章

      网友评论

          本文标题:2.第一篇:面向对象编程

          本文链接:https://www.haomeiwen.com/subject/eqvyfqtx.html