JS深入學習筆記 - 第二章.類和對象

来源:https://www.cnblogs.com/zry123/archive/2023/09/14/17701706.html
-Advertisement-
Play Games

3.類和對象 3.1面向對象 這裡順帶提一句學習JAVA時,老師說的面向對象和麵向過程的區別: 面向過程:強調做什麼事情,具體什麼步驟。舉個把大象放進冰箱的例子: 打開冰箱門 把大象放進冰箱 關上冰箱門 面向對象:強調的是做動作的主體(稱之為對象) 冰箱:打開操作 冰箱:放的操作(放的可以是大象也可 ...


3.類和對象

3.1面向對象

這裡順帶提一句學習JAVA時,老師說的面向對象和麵向過程的區別:

面向過程:強調做什麼事情,具體什麼步驟。舉個把大象放進冰箱的例子:

  1. 打開冰箱門
  2. 把大象放進冰箱
  3. 關上冰箱門

面向對象:強調的是做動作的主體(稱之為對象)

  • 冰箱:打開操作
  • 冰箱:放的操作(放的可以是大象也可以是老鼠)
  • 冰箱:關閉的操作

 

面向對象的思維特點:

  1. 抽取(抽象)對象共用的屬性和行為封裝成一個類(模板)
  2. 對類進行實例化,創建類的對象(具體的東西)

3.2對象

現實中:對象是一個具體的事物,比如一本書、一輛車、一個人。

在js中:對象是一組無序的相關屬性和方法的集合,所有的事物都是對象,如:字元串、數組、數值、函數等。

 

對象是由屬性方法組成的:

  • 屬性:事物的特征,在對象中用屬性來表示
  • 方法:事物的行為,在對象中用方法來表示

3.3 類

ES6中新增了類的概念,可以使用class關鍵字來聲明一個類,之後以這個類來實例化對象

類抽象了對象的公共部分,它泛指某一大類,

對象特指**某一個,通過類實例化一個具體的對**象。


類的本質:

  1. class本質還是function
  2. 類所有的方法都定義在類的prototype屬性
  3. 類創建的實例裡面也有__ proto__ 指向類的prototype原型對象
  4. 所以ES6的類的絕大部分功能。ES5都可以做到,新的class的寫法只是讓對象原型的寫法更加清晰、更面向對象編程的語法。
  5. 所以ES6的類其實就是語法糖
    class Father {
        
    }
    console.log(Father instanceof Function); //true
    //(1)類有原型對象prototype
    console.log(Father.prototype);
    //(2)類的原型對象prototype 裡面有 constructor 指向類本身
    console.log(Father.prototype.constructor);
    //(3)類可以通過原型對象添加方法
    Father.prototype.speak = function () {
      console.log("speak");
    };
    //(4)類創建的實例對象有 __proto__ 指向類的原型對象
    const zooey = new Father();
    console.dir(zooey.__proto__ === Father.prototype); //true
 

3.4創建類和實例化對象

 
//創建類
 class Star {
     //共有屬性放在constructor中
      constructor(uname, age) {
        this.name = uname;
        this.age = age;
      }
    }
    // 利用類實例化對象
    const ldh = new Star("劉德華", 19);
    const syz = new Star("孫燕姿", 18);
    //列印查看
    console.log(ldh);
    console.log(syz);
  • 註意:
  1. 通過class關鍵字創建類,類名首字母大寫。
  2. 類裡面有一個constructor函數,可以接收傳遞過來的函數,同時返回實例對象。
  3. 只要使用new生成實例時,就會調用constructor函數,如果我們不寫這個函數, 類也會自動生成這個函數

 

3.5類中添加方法

//創建類
    class Star {
      //共有屬性放在constructor中
      constructor(uname, age) {
        this.uname = uname;
        this.age = age;
      }
      sing(song) {
          //方法中可以this.使用實例屬性
        console.log(this.uname + "會唱" + song);
      }
    }
    // 利用類實例化對象
    const ldh = new Star("劉德華", 19);
    const syz = new Star("孫燕姿", 18);
    //列印查看
    console.log(ldh);
    console.log(syz);
    ldh.sing("忘情水");
    syz.sing("遇見");
  

 

註意:

  1. 類裡面的所有函數(方法)不需要寫function
  2. 多個函數方法(包括構造函數)之間不需要用 ',' 分割

4 類的繼承

現實中的繼承:子承父業,比如我們都繼承了父親的

程式中的繼承:子類可以繼承父類的一些屬性方法

4.1使用extends關鍵字實現繼承

 
   //創建父類類
    class Father {
      constructor(name, sex) {
        this.name = name;
        this.sex = sex;
      }
      money() {
        console.log(1000);
      }
    }
    // 創建子類並繼承父類
    class children extends Father {
    }
    const oldestSon = new children("伯邑考", "男");
    const middleSon = new children("姬發", "男");
    son.money();

4.2super關鍵字

一個錯誤使用案例:

 
    class Father {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      total() {
        return this.x + this.y;
      }
    }
    class Son extends Father {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
    }
    const son = new Son(1, 1);
    console.log("結果:" + son.total());

 

此時希望調用父類中的構造函數則需要使用到super

    class Father {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      total() {
        return this.x + this.y;
      }
    }
    class Son extends Father {
      constructor(x, y) {
        super(x, y);
      }
    }
    const son = new Son(1, 1);
    console.log("結果:" + son.total()); //結果:2

 

思考:看到這裡不知道你會不會和我有一樣的困惑,此時沒有super也可以實現 total方法的調用,所以 super存在真正的意義是什麼呢

思考案例1:

 
    class Father {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      total() {
        return this.x + this.y;
      }
    }
    class Son extends Father {
    }
    const son = new Son(1, 1);
    console.log("結果:" + son.total());

 

那麼就讓我們停下來思考一下:

當我們給Son構造函數傳遞多個參數的時候,這時,輸出的結果就不是我們想要的結果了,此時就必須使用super才能傳遞正確的參數了。

思考案例2:

 
   class Father {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      total() {
        return this.x + this.y;
      }
    }
    class Son extends Father {
  
    }
    const son = new Son(1, "女", "zooey", 1);
    
    console.log("結果:" + son.total());//結果:1女

真正意義上:

利用Son類創建實例son時,我們將實例son的參數傳遞給Son類的構造函數,

構造函數通過super()調用Father構造函數從而給this.x,this.y賦值,

從而使Father類中的total的方法能夠找到 this.x,this.y,

從而實現了思考案例1的結果。

 

沒有super時:

 

super關鍵字用於訪問和調用對象父類上的函數,可以調用父類的構造函數,也可以調用父類的普通函數。

super調用父類的方法

 
  class Father {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      total() {
        return this.x + this.y;
      }
    }
    
    class Son extends Father {
      constructor(x, y, z) {
        super(x, y);
        this.z = z;
      }
      total() {
        //子類方法中調用父類方法
        return this.z + super.total();
      }
    }
    const son = new Son(1, 1, 1);
    console.log("結果:" + son.total());//3

 

註意:子類的this賦值操作要放在super之後

 

註意事項:

  1. 在 ES6 中類沒有變數提升,必須先定義類,再實例化對象
  2. 類裡面共有是屬性和方法一定要加this使用
 
  class Star {
        constructor(name, age) {
          this.name = name;
          this.age = age;
          this.btn = document.querySelector("button");
          this.btn.onclick = this.sing;
        }
        sing() {
          console.log(this.name);
        }
      }
      const ldh = new Star("劉德華", 18);

 

4.3類中this指向

函數中的this一般指向調用者

下麵的代碼debug執行下,可以看到,sing()方法執行時,this是指向button的。

 

那麼正確的做法是什麼呢?

 
      let _this;
      class Star {
        constructor(name, age) {
          _this = this;
          this.name = name;
          this.age = age;
          this.btn = document.querySelector("button");
          //註意:因為這裡是點擊之後再調用,不是立即執行,所以是sing不是sing()
          this.btn.onclick = this.sing;
        }
 
        sing() {
            //使用 _this
          console.log(_this.name);
        }
 
 
      }
      const ldh = new Star("劉德華", 18);

 

總結:全局聲明一個this,然後調用後將它賦值給調用對象。

舉一反三:react中,常用的另一個方法是使用bind綁定this

 
  class Star {
        constructor(name, age) {
          this.name = name;
          this.age = age;
          this.btn = document.querySelector("button");
          this.btn.onclick = this.sing.bind(this);
        }
 
        sing() {
          console.log(this.name);
        }
      }
      const ldh = new Star("劉德華", 18);

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MySQL 存儲過程是一種強大的資料庫功能,它允許你在資料庫中存儲和執行一組SQL語句,類似於編程中的函數。存儲過程可以大幅提高資料庫的性能、安全性和可維護性。本文將詳細介紹MySQL存儲過程的使用。 什麼是MySQL存儲過程? MySQL存儲過程是一組預編譯的SQL語句,它們以一個名稱存儲在資料庫 ...
  • 近日,袋鼠雲大數據引擎專家郝衛亮,為大家帶來了《袋鼠雲在實時數據湖上的探索與實踐》主題分享,幫助大家能瞭解到什麼是實時數據湖、如何進行數據湖選型及數據平臺建設數據湖的經驗。 如今,大規模、高時效、智能化數據處理已是“剛需”,企業需要更強大的數據處理能力,來應對數據查詢、數據處理、數據挖掘、數據展示以 ...
  • 本文分享自華為雲社區《GaussDB(DWS)性能調優:Sort+Groupagg聚集引起的性能瓶頸案例》,作者: O泡果奶~ 。 本文針對SQL語句長時間執行不出來,且verbose執行計劃中出現Sort+GroupAgg聚集方式的案例進行分析。 1、【問題描述】 語句執行時間過長,2300s+也 ...
  • 自 3.0 版本發佈以來,在研發人員和社區用戶的不斷努力下,TDengine 做了大量更新,產品穩定性和易用性也在不斷提升。近日,TDengine 3.1.1.0 成功發佈,本文將向大家簡單介紹一下該版本涉及的重大更新。 寫在前面 伴隨 2023 年 9 月官網改版,TDengine 正式升級為高性 ...
  • 分享的 HTML 與上圖內容一樣,需要修改的小伙伴可以自行修改內容。 <style><!-- @import url("https://fonts.googleapis.com/css?family=Share+Tech+Mono|Montserrat:700"); * { margin: 0; p ...
  • 介紹 ESLint 是一個根據方案識別並報告 ECMAScript/JavaScript 代碼問題的工具,其目的是使代碼風格更加一致並避免錯誤。在很多地方它都與 JSLint 和 JSHint 類似,除了: ESLint 使用 Espree 對 JavaScript 進行解析。 ESLint 在代碼 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在 Web 開發中,非同步請求是一個常見的操作。然而,在非同步請求中正確地獲取返回值卻可能會變得棘手。本文將介紹如何解決非同步請求中的返回值問題,並提供一種解決方案。 一、問題描述 在某個 Web 應用程式中,用戶遇到了無法正確獲取非同步請求返回 ...
  • 介紹 在本文中,我試圖以最簡潔的方式來闡明JavaScript編程原理中對象類型賦值和原生類型賦值之間的區別,以及它們各自是如何工作的。這也是我希望在我的JavaScript編程生涯早期就已經理解的東西。 JS中的原生類型和對象類型 首先,讓我們回顧一下JavaScript中不同的原生類型和對象類型 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...