JS — 對象的基本操作

来源:https://www.cnblogs.com/keepitreal/archive/2019/01/16/10279596.html
-Advertisement-
Play Games

JS面向對象系列教程 — 對象的基本操作 面向對象概述  面向對象(Object Oriented)簡稱OO,它是一種編程思維,用於指導我們如何應對各種複雜的開發場景。 這裡說的對象(Object),意思就是事物,在面向對象的思維中,它將一切都看作是對象,並以對象為切入點去思考問題。 使用面向對象 ...


JS面向對象系列教程 — 對象的基本操作

面向對象概述

面向對象(Object Oriented)簡稱OO,它是一種編程思維,用於指導我們如何應對各種複雜的開發場景。

這裡說的對象(Object),意思就是事物,在面向對象的思維中,它將一切都看作是對象,並以對象為切入點去思考問題。

使用面向對象的思維去開發程式,我們首先思考的是這個系統中有哪些對象(事物),它們各自有什麼屬性(特征),又有什麼方法(行為),這樣一來,就可以把系統分解為一個一個的對象,然後對每個對象進行單獨研究,以降低系統的整體複雜度。

學習面向對象,我們不僅要學習它的技術知識,更重要的是學習這種思考程式的方式,這種思維方式跟我們過去開發程式有很大的區別。在過去,我們完成一個功能的時候,往往思考的是完成該功能的步驟,先做什麼,再做什麼,如果怎麼樣,就怎麼怎麼樣……,這種過去的思維模式,我們稱之為面向過程。

面向過程並不是錯誤的,只是它面對複雜的問題時顯得有些捉襟見肘。

面向過程和麵向對象最大的區別在於,面向過程思考的重心和切入點是事情,面向對象思考的重心和切入點是事物。

在面向對象的世界中,它將一切都看作是對象。這裡的對象,包羅萬象,它可以是現實世界中看得見摸得著的實體:人、小貓、小狗、飛機、課桌、鉛筆、電視等等等等,都可以看作是對象。它也可以是某些領域中的抽象體:訂單、價格計算器、dom元素、日期等等等等,它們也被看作是對象。

因此,在OO的世界里,有一句至理名言——一切皆為對象。

javascript語言是支持面向對象開發的語言,本系列教程中,將一步步講解如何使用它進行面向對象開發,同時會進一步探尋它背後深層次的原理。

註意:本系列教程的重心,將放在面向對象開發的技術層面(即面向對象編程,Object Oriented Programming,OOP)。

對於面向對象思想層面(即面向對象設計,Object Oriented Design,OOD),本教程不做過多講解。因為面向對象思想的建立並非一朝一夕,它不是靠讀文章讀出來的,雖然好的文章可以對你有啟發作用,但更多的,這種思想是靠常年累月的代碼量練出來的,是靠不斷的分析、重構想出來的。

本教程希望的是,你能夠通過學習面向對象開發,激發你的思考,引起你對另一種開發方式的關註,逐漸建立起面向對象的思維。

創建對象

對象即事物,一切皆對象。

其實你在之前的開發中,應該不止一次的接觸過對象,有些是瀏覽器自帶的對象,比如:dom對象、window對象、document對象等;有些則是你根據功能需要自己創建的,比如:用戶對象、學生對象等。

在JS中,創建一個對象非常的簡單,通過一對{}即可創建一個對象,下麵的代碼你應該並不會陌生:

const user1 = {    loginid: "bangbangji",    loginpwd: "123456",    name: "棒棒雞"};const user2 = {    loginid: "xiaobaitu",    loginpwd: "654321",    name: "小白兔"};

上面的代碼應該這樣理解,創建了兩個對象,分別把它們賦值給了變數user1和user2。

為什麼要強調這一點呢?因為真正的對象不是user1和user2,而是那一對大括弧及其裡面的內容{...},在後面講解對象賦值原理時還會詳細講解這一點。

上面這種創建對象的寫法,即使用兩個大括弧來表示對象{...},叫做對象的字面量表示法。

使用字面量表示法來創建對象的好處是簡單易懂,但它不好的地方在於無法應用面向對象開發中的一些高級特性。

下麵的代碼,展現了另一種創建對象的方式,即使用關鍵字new來創建對象:

const user1 = new Object(); //相當於:const user1 = {};user1.loginid = "bangbangji"; user1.loginpwd = "123456"; user1.name = "棒棒雞";const user2 = new Object(); //相當於:const user2 = {};user2.loginid = "xiaobaitu"; user2.loginpwd = "654321"; user2.name = "小白兔";

這樣的代碼雖然看似繁瑣了很多,但實際上它才是對象原本的創建方式。上面的代碼和第一種方式效果完全一致。

實際上,在JS語言中,所有的對象都是使用new關鍵字創建的。即便你使用的是字面量表示法,JS引擎最終也會將其轉換為這種方式。因此,對象的字面量表示法僅僅是JS語言的一個語法糖,要創建對象,最終都是要使用new關鍵字的。因此,在後文中,每一個示例,我都會用兩種方式來實現對象的創建。

語法糖(Syntactic sugar),也譯為糖衣語法,是指語言層面的一些便捷語法,它僅僅是為開發者提供的一種高效的編碼方式,並不改變底層的實現原理。

屬性和方法

我們過去使用對象,往往是為了將多個變數整合到一個變數上,其實,這種思想就是面向對象的一種核心思想——封裝。

面向對象有三大顯著特征:封裝、繼承、多態

那些整合到一個對象中的變數,我們稱之為對象的屬性。屬性往往是一個名詞,表示對象所擁有的特征。

const user1 = {    loginid: "bangbangji", //loginid為對象的屬性,表示用戶賬號    loginpwd: "123456", //loginpwd為對象的屬性,表示用戶密碼    name: "棒棒雞" //name為對象的屬性,表示用戶姓名};const user2 = new Object(); user2.loginid = "xiaobaitu";//loginid為對象的屬性,表示用戶賬號user2.loginpwd = "654321";//loginpwd為對象的屬性,表示用戶密碼user2.name = "小白兔";//name為對象的屬性,表示用戶姓名

對象的屬性還可以是一個對象或者數組或者其他任意類型,用於表示多層次的結構:

const user1 = {    loginid: "bangbangji",    loginpwd: "123456",    name: "棒棒雞",    //屬性address也是一個對象    address: {        province: "四川省",        city: "成都市"    } };//輸出:四川省-成都市console.log(`${user1.address.province}-${user1.address.city}`); const user2 = new Object(); user2.loginid = "xiaobaitu"; user2.loginpwd = "654321"; user2.name = "小白兔"; user2.address = new Object(); //屬性address也是一個對象user2.address.province = "四川省"; user2.address.city = "南充市";//輸出:四川省-南充市console.log(`${user2.address.province}-${user2.address.city}`);

對象除了有特征,還會有一些行為,這些行為我們稱之為對象的方法。方法往往是一個動詞,表示對象所擁有的行為,在代碼層面,方法表現為函數。

const user1 = {    loginid: "bangbangji",    loginpwd: "123456",    name: "棒棒雞",    //sayHello(打招呼)屬於對象方法,它是一個函數,表示對象的行為    sayHello: function () {        console.log("你好!");    } }; user1.sayHello(); //調用對象的方法,輸出:你好!const user2 = new Object(); user2.loginid = "xiaobaitu"; user2.loginpwd = "654321"; user2.name = "小白兔";//sayHello(打招呼)屬於對象方法,它是一個函數,表示對象的行為user2.sayHello = function () {    console.log("你好!"); }; user2.sayHello(); //調用對象的方法,輸出:你好!

可以看出,方法和屬性在書寫上並沒有本質的差別,只不過屬性是一個普通的值,方法是一個函數而已。

this關鍵字

我們現在考慮一下,在之前的示例中出現的sayHello方法,假設我們現在要對其功能做一點改造,我們希望該方法要輸出對象的姓名和賬號,於是,得到了下麵的代碼:

const user1 = {    loginid: "bangbangji",    loginpwd: "123456",    name: "棒棒雞",    //sayHello(打招呼)屬於對象方法,它是一個函數,表示對象的行為    sayHello: function () {        console.log("你好!我是棒棒雞,我的賬號是bangbangji");    } }; user1.sayHello(); //調用對象的方法,輸出:你好!我是棒棒雞,我的賬號是bangbangjiconst user2 = new Object(); user2.loginid = "xiaobaitu"; user2.loginpwd = "654321"; user2.name = "小白兔";//sayHello(打招呼)屬於對象方法,它是一個函數,表示對象的行為user2.sayHello = function () {    console.log("你好!我是小白兔,我的賬號是xiaobaitu"); }; user2.sayHello(); //調用對象的方法,輸出:你好!我是小白兔,我的賬號是xiaobaitu

這種方式結果固然正確,但是考慮一下100個用戶的場景……不敢想象是不?這還僅僅是一個打招呼的方法,如果方法裡面代碼多一點,複雜一點,會更加棘手。

由於同一類對象(比如這裡的用戶對象)都具有共同的行為——打招呼,我們何不把這個方法函數提出來呢?就像下麵這樣:

//提取出來的共同方法function sayHello(){    //怎麼辦?輸出哪個對象的姓名和賬號?    console.log("你好!我是???,我的賬號是???"); }const user1 = {    loginid: "bangbangji",    loginpwd: "123456",    name: "棒棒雞",    sayHello }; user1.sayHello(); //輸出:你好!我是???,我的賬號是???const user2 = new Object(); user2.loginid = "xiaobaitu"; user2.loginpwd = "654321"; user2.name = "小白兔"; user2.sayHello = sayHello; user2.sayHello(); //輸出:你好!我是???,我的賬號是???

這樣雖然解決了代碼重覆的問題,但新的問題又來了,雖然我們知道每個用戶對象都具有打招呼的方法,但是每個對象的屬性值不一樣,打招呼的時候,我到底輸出哪個對象的屬性值呢?

於是,JS給我們提供了一個關鍵字this,它指代的是當前對象,即調用方法的對象,於是我們就可以解決這個問題了:

//提取出來的共同方法function sayHello(){    //this指代當前調用方法的對象    console.log(`你好!我是${this.name},我的賬號是${this.loginid}`); }const user1 = {    loginid: "bangbangji",    loginpwd: "123456",    name: "棒棒雞",    sayHello };//user1調用sayHello時,方法運行過程中的this指代user1user1.sayHello(); //輸出:你好!我是棒棒雞,我的賬號是bangbangjiconst user2 = new Object(); user2.loginid = "xiaobaitu"; user2.loginpwd = "654321"; user2.name = "小白兔"; user2.sayHello = sayHello;//user2調用sayHello時,方法運行過程中的this指代user2user2.sayHello(); //輸出:你好!我是小白兔,我的賬號是xiaobaitu

我們在sayHello函數中使用了this關鍵字,當函數運行時,該關鍵字指代調用該函數的對象,即誰在調用我,我裡面的this就指代誰。在閱讀代碼的時候,你可以把this讀作我的,以便於你理解它。

藉助了神奇的this關鍵字,就解決了重覆代碼的問題,之後無論創建多少個用戶對象,我們都可以使用同一個方法了。

關於this關鍵字,目前你需要記住以下兩點:

this關鍵字只能書寫在函數內。

this關鍵字在函數運行的時候才能確定指代的是誰,函數運行前誰也無法知道它將指代誰。

由於javascript語言本身的特性,函數中的this關鍵字會帶來很多坑(比如直接調用sayHello函數,this指代誰呢?)。後面會專門拿一章出來講解this。

總結

面向對象(OO)是一種編程思維,以對象為切入點分析解決問題,這種思維需要長期的練習才能逐漸建立,而我們學習的是面向對象技術層面的東西。

創建對象可以使用字面量表示法和new關鍵字,字面量表示法是一個語法糖,JS引擎最終會將其變為new關鍵字方式創建對象。

對象包含屬性和方法,分別表示對象的特征和行為,它們沒有本質的區別,只是行為提現為一個函數

在函數中可以使用this關鍵字來指代**當前對象(調用函數的對象)


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

-Advertisement-
Play Games
更多相關文章
  • 效果如圖: 原圖 滑鼠進入後開始變化圖 實現需求: 頁面載入開始,效果如原圖所示,在滑鼠進入盒子後,圖片在當前滑鼠位置高亮顯示,其餘圖片變暗,依次交替進行。 代碼: 代碼分析: 1.頁面結構HTML+CSS: 盒子居中 margin:100px auto; 盒子中包括一個ul,li中包含img 2. ...
  • 一,效果圖。 二,代碼。 參考資料:《菜鳥教程》 ...
  • 標準,標準,什麼都有標準 你聽說過HTML5嗎?這是一個新版本,當然也有新標準 我只准備了一個index.html文件 以下是代碼 1 <!DOCTYPE html> <!--告訴瀏覽器這是一個html文件--> 2 <html> 3 <head> 4 <meta charset = "utf-8" ...
  • 嵌套標簽我們已經講一次了,在0X4.1里,我們把列表嵌套了 你覺得文字鏈接難看得令人作嘔,好,你再也不會有這種感覺了 一如既往,一個html文件和一個存放圖片的文件夾 index.html的代碼,很簡單 1 <html> 2 <head> 3 <title>TEST</title> 4 </head ...
  • 校驗基本日期格式: var reg = /^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2})$/; var r = fieldValue.match(reg); if (r==null) { alert('Date format error!'); } 校驗基本日期格 ...
  • a標簽不只是能鏈接到其他網頁,也能鏈接到網頁中的元素 class屬性讓你用CSS對特定的元素進行修飾 這些是一個網頁設計者的有力武器 這節課還是一個index.html文件 以下是代碼 以下是代碼 1 <html> 2 <head> 3 <title>TEST</title> 4 </head> 5 ...
  • 如果你認為列表只有ul和ol那你就錯了 我要為你展示新的列表 這次只有一個index.html文件 這是它的效果 以下是它的代碼 1 <html> 2 <head> 3 <title>TEST</title> 4 </head> 5 <body> 6 <!--嵌套列表--> 7 <p> 8 嵌套列表 ...
  • 想讓你的網頁變得整潔嗎?找我就對了,當然你會認識幾個新元素,和它們交朋友吧! 我幫你聯繫一下這幾個新元素,這樣交朋友就變得簡單了 images里放著圖片 以下是index.html的代碼 1 <html> 2 <head> 3 <title>Sagway'n USA</title> 4 </head ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...