美文网首页
JavaScript的面向对象

JavaScript的面向对象

作者: 蒋蒋_er | 来源:发表于2020-05-11 21:18 被阅读0次

    阅读说明:本文档默认已有ES5相关基础知识,包括构造函数、原型、继承等

    1.什么是面向对象

    • 面向过程POP VS 面向对象OOP

      <font color="#f00">面向过程</font>:分析出解决问题需要的步骤,然后用函数把这些步骤一步步实现,使用的时候再依次调用。

    ​ <font color="#f00">面向对象</font>:把事务分解成一个个对象,然后由对象之间分工与合作。

    例:把大象关进冰箱,分别用面向过程和面向对象来描述?

    ​ 面向过程:1. 打开冰箱

    ​ 2. 大象放进去

    ​ 3. 关上冰箱

    ​ 面向对象:先找出有哪些对象,这些对象有哪些功能?

    ​ 1. 大象对象(进去)

    ​ 2. 冰箱对象(打开、关上)

    ​ 3. 使用大象和冰箱的功能

    • 面向对象

      特性:封装性 继承性 多态性

      优点:易复用,易维护,易扩展

      缺点:没有面向过程性能高(面向过程适合和硬件联系紧密的东西,比如单片机)

      总结&比喻:蛋炒饭--面向过程 | 盖浇饭--面向对象

    2.类和对象

    面向对象可以形容现实世界的事物,事物分为具体的和抽象的两种,比如手机这是抽象的概念,但我手中的这个iphone 11就是具体的一部手机,是具体的概念。

    面向对象的思维:

    1. 抽取(抽象)对象共用的属性和行为组织(封装)成一个<font color="#f00">类</font>(模板)
    2. 对类进行实例化,获取类的对象
    • 对象和类的含义

      在JavaScript中,对象是一组无序的相关属性和方法的集合,所有事物都是对象。例如:字符串、数值、数组、函数等。

      ES6新增了一个概念类,使用class声明,之后以这个类实例化对象。类抽象了对象的公共部分,泛指某一大类。

    3. class创建自定义类

    如果不熟悉ES5的构造函数概念的,建议先熟悉构造函数以及对象的原型、继承等知识,参考经典红宝书,这样学习ES6中类的概念,会容易些。

    类的创建和实例化:

    class Star {
      // 构造函数,new创建对象时调用,可以接收传递过来的参数,同时返回实例对象
      constructor(uname) {
        this.uname = uname
      }
      // 实例方法(相当于ES5中Star.prototype.say=function)
      say() {
        console.log(this.uname)
      }
    }
    // 参数会传给constructor构造函数
    const xz = new Star("肖战")
    const cxk = new Star("蔡徐坤")
    xz.say()
    console.log(xz.uname, cxk.uname)
    

    4.什么是继承

    先看一个简单的继承的例子:

    // 父类
    class Father {
      constructor(x, y) {
        this.x = x
        this.y = y
      }
      sum() {
        console.log(this.x + this.y)
      }
    }
    
    // 子类(通过extends关键字实现继承,继承概念同ES5)
    class Son extends Father {
      // constructor函数可以没有,但如果定义了,则必须在使用this之前 调用super函数,否则报错,因为子类没有自己的this对象,而是继承父类的this
      constructor(x, y) {
        // 调用父类的构造函数
        super(x, y)
      }
    }
    var son = new Son(100, 5)
    son.sum()
    

    上面这个例子,如果子类Son没有constructor函数,最终结果也是一样的。因为子类如果不指定构造函数,会默认添加以下构造函数:

    constructor(...args) {
      super(...args);
    }
    

    super关键字除了可以调用父类构造函数,也能调用父类的普通方法:

    class Father {
      say() {
          console.log("Father")
      }
    }
    
    class Son extends Father {
      say(){
        //   调用父类的方法
          super.say()
          console.log("Son")
      }
    }
    var son = new Son()
    son.say()
    

    继承除了可以继承父类中的方法,也可以扩展子类自己的方法,定义方式和类定义方法一样。

    5.几个注意点

    • 类没有变量提升,所以使用自定义类创建实例化对象时,必须先声明这个类

    • 类里面共有的属性和方法加this使用

    • 注意this的指向:

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body>
          <button id="test">click!</button>
        </body>
        <script>
          var that
          var click_that
          var say_that
          class Star {
            constructor(name) {
              that = this
              this.anme = name
              this.btn = document.getElementById("test")
              this.btn.onclick = this.clickBtn
            }
            clickBtn() {
              click_that = this
              console.log(this) // button
              console.log(this.name) //undefined 因为这里的this指向的是button对象,不是实例化对象
            }
            say() {
              say_that = this
            }
          }
      
          var fa = new Star("肖战")
          fa.say()
          console.log(that === fa) //true
          console.log(click_that === fa) //false
          console.log(say_that === fa) //true
        </script>
      </html>
      

      上述代码比较简单,分别是打印了构造函数以及两个实例方法里this的指向,总结下:

      constructor中的this指向的就是实例对象,实例方法中的this指向,记住一个原则,谁调用的就指向谁

      比如上例中的click是button调用的,this指向this.btn,say方法是实例对象调用的,所以this指向实例对象fa。

      我在github写的一个关于面向对象的实例,这个实例主要是一个tab,包括删除、添加、双击编辑功能,采用的是面向对象的写法。

    相关文章

      网友评论

          本文标题:JavaScript的面向对象

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