面向对象

92 阅读3分钟

两大编程思想

1.面向过程

分析出解决问题所需要的步骤,用函数一一实现使用的时候在一个个调用

2.面向对象

把事务分解成一个个对象,然后由对象分工和合作

面向对象的特性

  • 封装性
  • 继承性
  • 多态性

两者的区别

面向过程没有面向对象易维护易复用易扩展

面向对象性能比面向过程低

面向对象思维特点

1.抽取对象公用的属性和行为组织(封装成)一个类(模板)

2.对类进行实例化

对象

对象特指某一个通过类实例化一个具体的对象

对象由属性和方法构成

  • 属性:事情的特征,在对象中用属性来表示
  • 方法:事务的行为

  • 在es6中增加了类的概念,可以用class关键字来声明一个类,之后用类来实例化对象

类抽象了对象的公共部分,泛指某一个大类

  • 创建类 语法

    class name{
    

    //class body } 创建实例

    var xx=new name();

注意类必须使用new实例化对象

  • 类constructor构造函数

constructor()方法时类的构造函数,可以接受传递过来的参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法,如果没有显示定义,类的内部会自动创建一个constructor()

     class name{
constructor(uname){
this.uname=uname;
      }
 }
 //利用类创建对象new
var aa=new name('11');
var bb=new name('22');

生成实例new不能省略

注意语法规范,创建类,类名后面不要加小括号,生成实例,类名后面加小括号,构造函数不需要加function

  • 类添加方法

     class name{
    constructor(uname){u
     this.uname=uname;
       }
     }
     say(){
    console.lod(this.name+'你好')
    
        }
    }
    

我们类里面所有的函数不需要加function

多个函数方法之间不需要添加逗号分隔

  • 类的继承

子类可以继承父类的一些属性和方法

 class father{
 }//父类
 class son extends father//子类继承父类
 例如:
 class Father{
constructor(x,y){
    this.x=x;
    this.y=y;
}
sum(){
    console.log(this.x+this.y);
}
 }
class son extends Father{
constructor(x,y){
    this.x=x;
    this.y=y;
}
 }
var son =new son(1,2);
son.sum();

 

super关键字

  1. super关键字用于访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数

    class Father{
    constructor(x,y){
     this.x=x;
     this.y=y;
     }
     sum(){
     console.log(this.x+this.y);
       }
      }
     class son extends Father{
     constructor(x,y){
      super();//调用了父类的构造函数
        }
     }
    var son =new son(1,2);
    son.sum();
    

2.super也可以调用父类的普通函数

       class Father {
    say() {
        return '我是爸爸'
    }
}

class son extends Father {
    say() {
        console.log(super.say() + '的儿子')
        //super.say() 就是调用父类中的普通函数
    }
}


var son = new son();
son.say();

继承中实例化子类输出一个方法,先看看子类有没有这个方法,有就执行子类美哟有的话就去父类执行这个方法

子类继承父类加法方法同时扩展减法方法

          class Father {
    constructor(x, y) {
    // constructor里面的this指向的是创建的实例对象
        this.x = x;
        this.y = y;
    }
    sum() {
    //方法中谁调用this就是指向谁
        console.log(this.x + this.y);
    }

}
class son extends Father {
    constructor(x, y) {
        super(x, y) //super必须在子类this之前调用
        this.x = x;
        this.y = y;
    }
    subtract() {
        console.log(this.x - this.y);
    }

}

var son = new son(5, 3);
son.subtract();
  • 类的注意点

1.在es6中类没有变量提升,所以必须先定义类,才能通过类实例化对象

2.类里面共有的属性和方法一定要加this使用

3.类中的this指向问题

  1. constructor里面的this指向的是实例对象,方法里面的this指向的是方法的调用者

面向对象案例

功能需求

1.店家tab栏可以切换效果

2.点击+号可以添加tab栏和内容项

3.点击x号可以删除当前的tab栏和内容项

4.双击tab项文字和内容项目的文字,可以修改里面的文字内容

             <!DOCTYPE html>
     <html lang="en">

     <head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../css/reset.css">
<style>
    nav {
        width: 500px;
        height: 50px;
        border: 1px solid #333;
        display: flex;
        justify-content: space-between;
    }
    
    nav ul {
        display: flex;
        padding: 0;
    }
    
    nav li {
        list-style-type: none;
        border-right: #333 solid 2px;
        width: 60px;
        padding: 0;
        text-align: center;
        line-height: 50px;
        position: relative;
    }
    
    .guanbi {
        position: absolute;
        right: 0;
        top: -20px;
    }
    
    .tabscon section:nth-child(2),
    .tabscon section:nth-child(3) {
        width: 500px;
        height: 200px;
        border: 1px solid #333;
        display: none;
    }
    
    .conactive {
        width: 500px;
        height: 200px;
        border: 1px solid rgb(218, 37, 37);
        background-color: aqua;
        display: block;
    }
    
    .liactive {
        background-color: pink;
        color: white;
    }
</style>
   </head>

      <body>
<h4>js面向对象 动态添加标签页</h4>
<div class="tabsbox" id="tab">
    <!-- tab标签 -->
    <nav class="fisnav">
        <ul>
            <li class="liactive"> <span>测试1</span> <span class="guanbi">x</span></li>
            <li>
                <span>测试2</span>
                <span class="guanbi">x</span>
            </li>
            <li>
                <span>测试3</span>
                <span class="guanbi">x</span>
            </li>
        </ul>
        <div class="tabadd">
            <span>+</span>
        </div>
    </nav>
    <!-- tab内容 -->
    <div class="tabscon">
        <section class="conactive">测试1</section>
        <section>测试2</section>
        <section>测试3</section>
    </div>
</div>
      </body>
         <script>
var that;
class Tab {
    constructor(id) {
        that = this;
        //获取元素
        this.main = document.querySelector(id);
        this.lis = this.main.querySelectorAll('li')
        this.sections = this.main.querySelectorAll('section')
        this.add = this.main.querySelector('.tabadd')
        this.ul = this.main.querySelector('.fisnav ul:first-child')
        this.fsection = this.main.querySelector('.tabscon')
        this.remove = this.main.querySelectorAll('.guanbi')
        this.init();
    }
    init() {
            this.updateNode()
            this.add.onclick = this.addTab;
            // init初始化操作让相关的元素绑定事件
            // 绑定点击事件
            for (var i = 0; i < this.lis.length; i++) {
                this.lis[i].index = i;
                this.lis[i].onclick = this.toggleTab;
                this.remove[i].onclick = this.removeTab
                this.spans[i].ondblclick = this.editTab
                this.sections[i].ondblclick = this.editTab
            }
        }
        //切换功能
    toggleTab() {

            that.clearClass();
            this.className = 'liactive';
            that.sections[this.index].className = 'conactive';


        }
        // 获取所有li和section
    updateNode() {
        this.lis = this.main.querySelectorAll('li')
        this.sections = this.main.querySelectorAll('section')
        this.remove = this.main.querySelectorAll('.guanbi')
        this.spans = this.main.querySelectorAll('.fisnav li span:first-child')


    }
    clearClass()

    // 清除所有li个section的类
    {
        for (var i = 0; i < this.lis.length; i++) {
            this.lis[i].className = '';
            this.sections[i].className = '';
        }
    }
    addTab() {
            // 清除所有li个section的类
            that.clearClass();
            //    创建li元素和section元素
            var li = '<li class="liactive"> <span>新测试</span> <span class="guanbi">x</span></li>'
            var section = ' <section class="conactive">测试3</section>'
                // 把创建的两个元素追加到对应的父元素里
            that.fsection.insertAdjacentHTML('beforeend', section);
            that.ul.insertAdjacentHTML('beforeend', li);
            that.init();
            //利用insertAdiacentHTML()可以直接把字符串格式元素添加到元素里
        }
        // 删除事件
    removeTab(e) {
            // 防止冒泡,防止触发li的切换点击事件
            e.stopPropagation();
            var index = this.parentNode.index;
            console.log(index)
                // 根据索引号删除对应的li和section
            that.lis[index].remove();
            that.sections[index].remove();
            that.init();
            // 当我们删除的不是这个li的时候,原来的选中状态li保持不变
            if (document.querySelector('.liactive')) return;
            // 当我们删除选中状态的这个li的时候,让他前一个li处于选定状态
            index--
            // 手动调用我们的点击事件 不需要鼠标触发
            that.lis[index] && that.lis[index].click();

        }
        // 编辑功能
        //双击事件ondblclick 双击后默认选定文字需要双击禁止选中文字
    editTab() {
        // 禁止双击选中文字
        var str = this.innerHTML
        window.getSelection ? window.getSelection().removeAllRanges() : document.section.empty();
        this.innerHTML = '<input type="text"/>'
        var input = this.children[0]
        input.value = str
        input.select(); //让文本框里面的文字处于选定状态
        // 当我们离开文本框九八文本框的值给span
        input.onbur = function() {
                this.parentNode.innerHTML = this.value
            }
            // 按下回车可以把文本框里面的值给span
        input.onkeyup = function(e) {
            if (e.keyCode === 13) {
                //手动调用扁担失去焦点事件,不需要鼠标离开操作
                this.blur();
            }
        }

    }
}
new Tab('#tab');
   </script>

      </html>