Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 影音先锋中文字幕资源,亚洲精品视频免费在线观看,国产欧美日韩精品a在线观看高清 国产欧美日韩精品在线

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript系列-1-面向對象

          JavaScript系列-1-面向對象

          向過程和面向對象編程概述

          面向過程編程就是分析出解決問題的步驟,然后使用函數把這些步驟一步步實現,重心放在完成的每個過程上。

          面向對象則是以封裝的思想,將問題分析得到的數據封裝成一個個的對象,然后通過對對象的操作來完成相應的功能。

          舉個栗子:廚師炒菜

          以面向過程的思想來分析應該分為下面幾個步驟:

          ? 1.檢查食材是否齊全 2.如果不不夠,去菜市場買菜 3.洗菜 4.開火 5.按炒菜(按順序放入相應的食材,調料等) 6.出鍋裝盤

          以面向對象的思想分析則是這樣的:

          ? 1.廚師,檢查食材,炒菜 2.采購員,去菜市場買菜 3.墩子,洗菜,切菜,備菜

          ? 通過調用上面對象中的行為方法即可完成炒菜的整個過程

          從上面的例子可以看出,面向對象和面向過程最大的不同在于,面向對象關心的是由哪些對象,每個對象應該有哪些功能,而面向過程關心的是實現過程中的每個步驟。

          那么這兩種思想到底孰優孰劣呢?從表面上看,貌似面向對象更好,為什么呢?因為它完全符合我們的正常思維方式,所以在接受度方面,面向對象的思想肯定是更好。但是面向過程也有他的優勢,就是靈活便捷,而面向對象相對來說會更耗資源,更慢一點。

          所以,至于以后使用哪一種,這就需要看我們的具體需求,根據不同的需求做不同的選擇。

          面向對象編程的相關概念

          通過上面的分析,我們知道面向對象的重點在于功能分析和對象的封裝上,那么最終我們得到的對象的結構是怎樣的,我們繼續往下學習。

          比如,我通過對人的分析得到,每個人都有姓名,年齡,性別等屬性,同時也有吃飯睡覺等行為,那么用JS可以做如下的封裝:

          var p={
              name : "xiao song",
              age : 10,
              sex : 1,
              eat : function () {
                  console.log("吃飯");
              },
              sleep : function () {
                  console.log("睡覺");
              }
          }
          console.log(p.name);//訪問對象的屬性
          p.eat();//訪問對象的方法
          

          上面的p則表示一個對象,其中的name / age / sex稱之為對象的屬性,eat / sleep 稱之為對象的方法,我們通過訪問該對象的屬性或者方法達到相應的目的即可。

          DOM操作相關知識點復習

          在學習了html之后我們發現,html文檔中的內容其實就是由一堆的標簽組成,由于在后面的課程中需要使用到html,所以我們先大致的回顧一下它的結構。

          <div id="div1" class="clz1">
              <h3>H5-JS面向對象</h3>
          </div>
          

          div h3:元素節點

          id class:屬性節點

          H5-JS面向對象:文本節點

          一個html文檔主要由這三部分組成,DOM(文檔對象模型)是對操作這些元素的屬性或者方法進行了封裝,從而達到方便快捷的操作html的目的。

          獲取元素對象:document.getElementById(“div1”)

          訪問元素的屬性:div1.className

          訪問元素的文本內容:div1.innerText

          增刪改元素:div1.appendChild(newNode)

          下面,我們就通過這些API來講解說明面向對象相關的內容。

          創建并設置標簽(面向過程)

          需求1:創建三個div元素,并設置邊框,背景色,文本及字體顏色

          for (var i=0; i < 3; i++) {
          	var div=document.createElement("div");
          	div.innerText="div"+i;
          	div.style.backgroundColor="green";
          	div.style.border="1px solid #000";
          	div.style.color="white";
          	document.body.appendChild(div);
          }
          

          需求2:為頁面中存在的三個P元素設置邊框,背景色,文本及字體顏色

          <p>我是P1</p>
          <p>我是P2</p>
          <p>我是P3</p>
          <script>
              var ps=document.getElementsByTagName("p");
              for (var i=0; i < ps.length; i++) {
                  ps[i].style.backgroundColor="red";
                  ps[i].style.border="1px solid #000";
                  ps[i].style.color="white";
              }
          </script>
          

          需求3:獲取頁面上三個class=“test”的元素,設置邊框,背景色,文本及字體顏色

          <h3 class="test">我是標題1</h3>
          <h3 class="test">我是標題2</h3>
          <h3 class="test">我是標題3</h3>
          
          <script>
          	var tests=document.getElementsByClassName("test");
          	for (var i=0; i < tests.length; i++) {
          	    tests[i].style.backgroundColor="yellow";
          	    tests[i].style.border="1px solid #000";
          	    tests[i].style.color="red";
          	}
          </script>
          

          上面的代碼是以面向過程的思想完成的,可以看到,兩個需求中的每個步驟都是我們一步一步完成的,問題很明顯,代碼大量的冗余,這種代碼后期不好維護。

          創建并設置標簽(函數封裝)

          對于上面重復的代碼,我們可以使用函數對其進行封裝

          <script>
              function setStype(eles,bgcolor) {
                  for (var i=0; i < eles.length; i++) {
                      eles[i].style.backgroundColor=bgcolor;
                      eles[i].style.border="1px solid #000";
                      eles[i].style.color="white";
                  }
              }
              function getElementsByTagName(tagName) {
                  return document.getElementsByTagName(tagName);
              }
              function getElementsByClassName(className) {
                  return document.getElementsByClassName(className);
              }
              var ps=getElementsByTagName("p")
              setStype(ps,"green");
              var tests=getElementsByClassName("test");
              setStype(tests,"red");
          </script>
          

          封裝了三個函數:

          1. setStype(eles,bgcolor):為元素設置樣式? eles:哪些元素? bgcolor:背景色
          2. getElementsByTagName(tagName):根據元素名稱獲取指定的元素? tagName:元素名
          3. getElementsByClassName(className):根據class屬性名獲取指定的元素? className:class屬性名

          接下來就是調用三個方法完成了上面的需求,解決了第一種方式中大量的重復代碼的問題。

          但是,這種方式仍然存在問題。在前面JS基礎中說過,我們應該盡量避免大量使用全局變量,這會降低程序的執行效率,在上面的程序中,我們就出現了5個(包括函數)。所以需要繼續優化。

          創建并設置標簽(面向對象)

          使用面向對象的思想來解決上面的問題,我們可以將上面的三個函數都裝到一個對象中

          var $={
              setStype:function (eles,bgcolor) {
              	for (var i=0; i < eles.length; i++) {
              	    eles[i].style.backgroundColor=bgcolor;
              	    eles[i].style.border="1px solid #000";
              	    eles[i].style.color="white";
              	}
              },
              getElementsByTagName: function (tagName) {
                  return document.getElementsByTagName(tagName);
              },
              getElementsByClassName:function (className) {
                  return document.getElementsByClassName(className);
              }
          }
          var ps=$.getElementsByTagName("p")
          $.setStype(ps,"green");
          var tests=$.getElementsByClassName("test");
          $.setStype(tests,"red");
          

          后面如果我們還都需要封裝其他功能,可以直接在$這個對象中添加即可

          如,根據元素的id屬性獲取元素,并為其設置樣式

          getElementById:function (eleId) {
          	return [document.getElementById(eleId)];
          }
          

          需要注意的是,在設置樣式方法中,我們默認是將傳遞進來的元素當做數組進行處理的,所以,在這里,我們在getElementById方法中,手動將獲取到的元素添加到數組中返回。

          通過觀察,在$對象中,存在三個獲取元素的方法,這里我們最好將其按照下面的方式來歸類

          var $={
              getElements:{
                  byTagName: function (tagName) {
                      return document.getElementsByTagName(tagName);
                  },
                  byClassName:function (className) {
                      return document.getElementsByClassName(className);
                  },
                  byId:function (eleId) {
                      return [document.getElementById(eleId)];
                  }
              },
              setStype:function (eles,bgcolor) {
                  for (var i=0; i < eles.length; i++) {
                      eles[i].style.backgroundColor=bgcolor;
                      eles[i].style.border="1px solid #000";
                      eles[i].style.color="white";
                  }
              }
          }
          

          將獲取元素的方法封裝到$對象的getElements屬性中,今后如果還有其他獲取元素的方法,都應該是添加到getElements屬性中,其他類型的方法也應該按照這種思想進行封裝。

          面向對象編程的三大特性

          面向對象的特性:

          1. 封裝作用:復用和信息隱藏封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。
          2. 繼承它可以使用現有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。通過繼承創建的新類稱為“子類”或“派生類”。被繼承的類稱為“基類”、“父類”或“超類”。繼承的過程,就是從一般到特殊的過程。
          3. 多態當存在繼承關系時,允許將父類對象看成為和它的一個或多個子類對象等同.這樣,可以根據當前賦給父類對象的子對象的具體特性以不同的方式進行運行.

          用字面量方式創建對象

          直接使用字面量方式創建對象比較方便,以鍵值對的格式來定義數據

          var book1={
              name:"JavaScript權威指南",
              price:100,
              author:"tim",
              showInfo:function () {
                  console.log(this.name,this.price,this.author);
              }
          }
          console.log(book1);
          

          上面定義了一個書對象,并為其添加了屬性和方法,我們也可以直接訪問其中的屬性和方法。

          這種方式的弊端是,如果需要創建多個類似的對象,就顯得不太方便了,會出現大量的重復代碼。

          也就是說,這種方式不適合創建大量的相同或相似的對象。

          內置構造函數和簡單工廠創建對象

          使用new關鍵字+內置的構造函數創建對象

          var book2=new Object();
          book2.name="JS";
          book2.price=10;
          book2.author="作者";
          book2.showInfo=function () {
              console.log(this.name,this.price,this.author);
          }
          book2.showInfo();
          

          這種方式和字面量方式創建對象存在的問題差不多,在大量創建對象的時候都會存在大量重復的代碼。

          那么,利用前面的封裝的思想,我們應該可以想到,當有重復代碼的時候,我們可以將這些重復代碼抽取到函數中來解決。

          function createBook(name, price, author) {
              var book=new Object();
              book.name=name;
              book.price=price;
              book.author=author;
              book.showInfo=function () {
                  console.log(this.name,this.price,this.author);
              }
              return book;
          }
          var book3=createBook("bookName1",10,"author1");
          var book4=createBook("bookName2",10,"author2");
          console.log(book3);
          console.log(book4);
          

          我們將創建book對象的代碼封裝到createBook函數中,當需要創建一個book對象的時候,直接調用該函數,將函數需要的參數傳遞過去即可。

          那么,相同的思想,如果我們需要創建其他的對象,一樣可以使用封裝函數的方法來解決,這是沒問題的。

          function createPerson(name, age) {
              var p=new Object();
              p.name=name;
              p.age=age;
              return p;
          }
          console.log(createPerson("Neld", 10))
          

          利用上面的函數,我們可以創建一個Person對象出來,但是通過打印對比,我們無法通過創建出來的對象判斷該對象的類型,而在實際開發中,判斷對象的類型是我們經常需要執行的,所以我們繼續看下面的自定義構造函數創建對象。

          自定義構造函數創建對象

          構造函數和普通的函數的定義方式完全一樣,如下,我們定義一個創建Person的構造函數

          function createPerson(name, age, sex) {
              this.name=name;
              this.age=age;
              this.sex=sex;
          }
          var p=new createPerson("Neld", 10, 1);
          var p2=new createPerson("Song", 12, 0);
          console.log(p);
          console.log(p2);
          

          自定義函數和工廠函數非常相似,但是還是存在很大的區別

          1. 構造函數名的首字母要求大寫
          2. 需要使用new關鍵字和構造函數一起創建對象
          3. 在函數中,不需要手動創建對象進行數據封裝,會自動創建并封裝數據
          4. 在函數最后,不需要手動返回創建好的對象,會自動返回

          到這里,大家肯定會有疑問,自定義構造函數到底是如何創建并封裝對象呢?

          1. 在函數內部默認會創建一個空對象 var obj=new Object();
          2. 默認把創建好的對象賦值給this this=obj;
          3. 默認設置this的原型對象為當前構造函數的原型對象
          4. 通過this添加屬性和方法
          5. 默認會把內部創建的對象返回 return this;

          通過上面的分析,相信大家已經能夠理解自定義構造函數的基本使用以及基本的原理了。

          構造函數創建對象的返回值

          默認情況下,構造函數內部會返回新創建好的對象(this)

          主動返回:

          1. 如果返回值類型的數據,仍然返回創建好的對象(this),不做任何修改
          2. 如果返回引用類型的數據,則返回指定的數據,不再返回this。

          函數作為構造函數參數使用

          在JS世界里,函數屬于一等公民,擁有最高特權,在使用過程中可以作為變量賦值,可以作為參數傳遞,也可以作為函數的返回值,下面我們具體來看看他的使用。

          函數作為參數使用

          function f1(name,age,fn) {
              console.log("name:",name,"age:",age);
              fn();
          }
          function fn(){
              console.log("Hello H5");
          }
          f1("Neld", 10, fn);
          

          輸出結果:

          ? name: Neld age: 10? Hello H5

          在上面的代碼中,我們將函數fn作為參數傳遞給了函數f1,并且在函數f1中調用,得到的相應的打印輸出。

          函數作為返回值使用

          function f1(name,age,fn) {
              console.log("name:",name,"age:",age);
              return fn;
          }
          function fn(){
              console.log("Hello H5");
          }
          var retFun=f1("Neld", 10, fn);
          retFun();
          

          在函數f1中將傳遞進來的fn作為返回值返回,接收到調用f1之后的返回值得到的是返回的函數,然后再調用retFun得到打印結果。

          此時的f1為高階函數,即參數中有一個或多個函數,并且把函數作為返回值。

          此時的fn為回調函數,fn作為參數傳遞給函數f1,在f1內部調用。

          函數作為構造函數的參數使用

          function createPerson(name, age, sex, say) {
              this.name=name;
              this.age=age;
              this.sex=sex;
              this.say=say;
          }
          var p=new createPerson("Neld", 10, 1, function () {
              console.log("say hello");
          });
          var p2=new createPerson("Song", 12, 0,function () {
              console.log("say bye");
          });
          p.say();
          p2.say();
          

          在構造函數中也可以對方法進行封裝,如果方法的實現是由調用者決定的,那么可以在構造函數中接收一個函數對象,然后在構造函數中進行封裝。

          如上面的函數say,在創建p和p2對象的時候傳遞并賦值給形參say,然后在構造函數中賦值給當前對象。

          構造器屬性

          前面說到工廠函數創建對象是比較方便的,但是存在一個問題就是無法得知創建出來的對象的類型,所以我們選擇使用自定義的構造函數來創建,構造函數創建對象我們已經會使用了,那么如何通過他得知創建對象的類型呢?這里我們提供兩種方式。

          1. constructor屬性

          使用constructor屬性可以獲取到創建對象使用的構造器函數對象,所以我們可以通過判斷構造器的類型來得知創建的對象的類型

          2.instanceof關鍵字


          instanceof關鍵字可以直接用來判斷對象的類型,如果是指定的類型,返回true,反之返回false。

          構造函數的調用和命名

          在學習了構造函數之后,有的同學對于它和普通函數的區別還是不太清楚,這里我們就再對構造函數做一個說明。

          1. 構造函數和普通函數在定義語法上沒有任何區別function 函數名(參數列表){代碼塊;}
          2. 為了和普通函數區分開,我們約定將構造函數的名稱首字母大寫
          3. 構造函數一樣可以直接調用,此時內部的this執行window,這種方式不太安全,有可能會在函數內部修改當前的全局變量,不建議使用,而且這樣做也不能創建對象
          4. 想要創建對象,必須使用new和構造函數一起使用

          函數上下文和this指針

          在JS編程的過程中發現,我們大量使用到this關鍵字,用好了this,能讓我們的代碼更加優雅。

          this總是執行一個對象(引用類型),但是具體執行誰,需要根據我們在哪里使用this有關。這里主要分為下面幾種情況:

          1. 函數外部函數外部的作用域是全局作用域(window),所以,在全局作用域中使用的this指向window
          2. 普通函數內部函數內部的作用域是局部的,屬于調用當前函數的對象,所以this執向調用當前函數的對象
          3. 構造函數內部在構造函數中,this直接執行當前創建出來的新對象

          在開發中,我們也可以使用call或者apply函數修改this的執行,這一點我們在后面繼續說明。

          自定義構造函數存在的問題

          自定義構造函數可以解決工廠函數帶來的對象類型不確定的問題,在開發中用得非常多,那么目前我們的自定義構造函數又是否存在問題呢?先來看看下面的對象內存結構分析。

          function Person(name, age, say) {
              this.name=name;
              this.age=age;
              this.say=function(){
                  console.log("say hello");
              }
          }
          var p=new Person("zs", 10, say);
          console.log(p);
          

          上面創建的p對象的內存結構圖:

          可以看出,我們每創建一個Person對象,都會在內存中分配如0x22和0x33這樣的內存來存儲數據,但是通過觀察發現,0x33中存儲的是一個函數,而這個函數在每個對象中都是相同

          所以從內存資源分配考慮,我們無需為每個對象創建并分配一份新的函數對象(完全相同),這種函數大家最好共享同一份。

          文共3525字,預計學習時長12分鐘

          圖源:pexels

          一切都從對象開始。

          對象,即我們相互交流的一個載體,有其屬性和方法。對象是面向對象編程的核心,不僅用于JavaScript,而且還適用于Java、C語言、C++等。不再考慮單個變量和函數,而選擇自給型的對象。

          以下是在討論面向對象編程(OOP)時最常用到的概念:

          · 對象,屬性,方法

          · 類

          · 封裝

          · 抽象

          · 復用/繼承

          · 多態性

          · 關聯

          · 聚合

          · 組合

          1. 對象,屬性,方法

          1.1 對象字面量(Objectliteral)

          在大括號中設置屬性,從而在JavaScript中創建一個新對象。對象字面量屬性值可以是任何數據類型,如函數字面量、數組、字符串、數字或布爾值。

          下面創建一個命名圖書的對象,其屬性包括作者、出版年份、標題和方法。

          — summary.

          constbook={
          title: "Hippie",
          author: "Paulo Coelho",
          year: "2018"
          }

          對象創建完成后,可以使用點記法獲取值。例如,可以使用book.title.獲取標題的值,還可以使用方括號book[‘title’]訪問屬性。

          1.2 對象構造函數(Objectconstructor)

          對象構造函數與常規函數相同。每次創建對象時都會用到。可將其與新關鍵字一起使用。當需要創建具有相同屬性和方法的多個對象時,對象構造函數非常有用。

          constbook={

          title: "Hippie",
          author: "Paulo Coelho",
          year: "2018"
          }const book1={
          title: "The Alchemist",
          author: "Paulo Coelho",
          year: "1988",
          }

          如果要創建多個書籍(book)對象,必須為每本書復制代碼。可以繼續創建 book對象,但這有點麻煩——不過對象構造函數有助于再次使用對象字面量。

          functionBook(title, author, year) {
          this.title=title;
          this.author=author;
          this.year=year;
          }const book1=new Book ('Hippie', 'Paulo Coelho',

          '2018');

          console.log(book1);

          > Book {
          title: "Hippie",
          author: "Paulo Coelho",
          year: "2018"
          }// if we want to create more than onebook just we call

          function book with new keyword.const book2

          =new Book ('TheAlchemist', 'Paulo Coelho', '1988');

          book1 和 book2創建 Book的實例并將其分配給變量。想知道一個對象是否是另一個對象的實例。可以用instanceof。

          book1 instanceof Book

          > true

          1.3 Object.create()方法

          JavaScript中的每個對象都將從主對象創建。任何時候使用大寫字母“O”時,指的都是主對象。我們可以在console控制臺中打印主對象。主對象有很多方法,下面來看object.create()方法。

          Object.create()創建法使用現有對象作為原型來創建新對象。基本語法如下:

          Object.create(proto,[propertiesObject])

          proto是新建對象的原型。 propertiesObject是一個可選項。

          下面舉個簡單的例子:

          constBook={
          summary : function() {
          console.log(`${this.title} iswritten by ${this.author}.`)
          }
          }const book1=Object.create(Book);
          book1.author="Paulo Coelho";
          book1.title="Hippie";console.log(book1.summary());
          > Hippie is written by Paulo Coelho.

          以上的例子創建了一個原始對象book1,并為作者和標題賦值。可以看到原始對象中的匯總函數:

          下面將Object.create() 方法進行詳細介紹。

          2. 類

          類不是對象,它是對象的藍本,是特殊函數。可以使用函數的表達式和聲明來定義函數,也可以這樣定義類。藍本可用來表示對象的數量。

          可以使用類的關鍵字和名稱。語法與Java相似。

          類語法是使用面向對象編程和管理原型的一個好途徑:

          let Book=function(name) {
          this.name=name
          }let newBook=function(name) {
          Book.call(this, name)
          } newBook.prototype=Object.create(Book.prototype);
          const book1=new newBook("The Alchemist");

          此例使用了ES6類語法:

          classBook {
          constructor(name) {
          this.name=name
          }
          }class newBook extends Book {
          constructor(name) {
          super(name);
          }
          }const book1=new newBook("The Alchemist");

          類語法是語法糖(syntactical sugar)—而場景背后它仍然使用基于原型的模型。類是函數,而函數是JavaScript中的對象。

          classBook {
          constructor(title, author){
          this.title=title;
          this.author=author;
          }
          summary() {
          console.log(`${this.title} writtenby ${this.author}`);
          }
          }const book1=new Book("", "");

          console.log(typeof Book);
          > "function"console.log(typeof book1);
          > "object"

          3. 封裝(Encapsulation)

          封裝意為隱藏信息或數據。指對象在不向外部使用者透露任何執行細節的情況下執行其功能。換句話說,就是其私有變量只對當前函數可見,而對全局范圍或其他函數不可訪問。

          constBook=function(t, a) {
          let title=t;
          let author=a;
          return {
          summary : function() {
          console.log(`${title} written by${author}.`);
          }
          }
          }
          const book1=new Book('Hippie', 'Paulo Coelho');

          book1.summary();
          > Hippie written by Paulo Coelho.

          在上面的代碼中,標題和作者只在函數Book 的范圍內可見,方法summary對Book的使用者可見。所以書名和作者被封裝在Book中。

          4. 抽象

          抽象意為實現隱藏。它是一種隱藏實現細節的方法,只向使用者顯示基本特性。換句話說,它隱藏了不相關的細節,只顯示了必須對外部世界顯示的。缺乏抽象會導致代碼出現可維護性問題。

          constBook=function(getTitle, getAuthor) {

          // Private variables / properties
          let title=getTitle;
          let author=getAuthor;// Publicmethod
          this.giveTitle=function() {
          return title;
          }
          // Private method
          const summary=function() {
          return `${title} written by${author}.`
          }// Public method that has access toprivate method.
          this.giveSummary=function() {
          return summary()
          }
          }const book1=new Book('Hippie', 'Paulo Coelho');

          book1.giveTitle();
          > "Hippie"book1.summary();
          > Uncaught TypeError: book1.summary is not a

          functionbook1.giveSummary();
          > "Hippie written by Paulo Coelho."

          5. 復用/繼承

          JavaScript繼承是一種機制,允許我們使用現有的類創建一個新類。也就是子類繼承父類的所有屬性和行為。

          一般來說,JavaScript不是一種基于類的語言。關鍵字“類”是在ES6中引入的,但它是語法糖,JavaScript仍然是基于原型的。在JavaScript中,繼承是通過使用原型來實現的。這種模式稱為行為委托模式或原型繼承。

          同樣可以通過book例子來體現:

          functionBook(title, author, year) {

          this.title=title;
          this.author=author;
          this.year=year;
          this.summary=function() {
          console.log(`${this.title} iswritten by ${this.author}.`)
          }
          }
          const book1=new Book ('Hippie', 'Paulo Coelho', '2018');

          const book2=newBook ('The Alchemist', 'Paulo Coelho',

          '1988');

          原型繼承

          對于Book的每個實例,我們都在為基類中的方法重建內存。這些方法必須在所有實例之間共享 — 不應特定于個別實例中。圖中的原型是:

          letCorebook=function(title) {

          this.title=title
          }Corebook.prototype.title=function() {
          console.log(`name of the book is${this.title}`);
          }Corebook.prototype.summary=function(author) {
          console.log(`${this.title} is writtenby ${this.author}`);
          }let Book=function(title, author) {
          Corebook.call(this, title, author)
          }Book.prototype=Object.create(Corebook.prototype);

          let book1

          =new Book('TheAlchemist', 'Paulo Coelho');book1.title();
          > name of the book is The Alchemistbook1.summary();
          > The Alchemist is written by Paulo Coelho

          在上面的代碼中,Book 的實例有一個原型的副本,能夠鏈接到Book的原型,而Book的原型又鏈接到Corebook的原型。

          6. 多態

          在不同的對象上使用同一方法,并讓每個對象具有自己的表現形式或形態的能力,稱為多態。

          letbook1=function () {}

          book1.prototype.summary=function() {
          return "summary of book1"
          }let book2=function() {}
          book2.prototype=Object.create(book1.prototype);
          book2.prototype.summary=function() {
          return "summary of book2"
          }let book3=function() {}
          book3.prototype=Object.create(book1.prototype);
          book3.prototype.summary=function() {
          return "summary of book3"
          }
          var books=[new book1(), new book2(), new book3()];
          books.forEach(function(book){
          console.log(book.summary());
          });> summary of book1
          > summary of book2
          > summary of book3

          對象之間的關系將由關聯、聚合和組合定義。

          7. 關聯

          關聯是兩個或多個對象之間的關系。每個對象都是獨立的。換句話說,關聯定義了對象之間的多重性:一對一、一對多、多對一、多對多。

          functionBook(title, author) {
          this.title=title;
          this.author=author;
          }

          const book1=new Book ('Hippie', 'Paulo Coelho');

          const book2=new Book ('TheAlchemist',

          'Paulo Coelho');

          book2.multiplicity

          =book1

          book1 賦值于book2的屬性多樣化,顯示對象book1 和 book2之間的關系。兩者都可以獨立添加和刪除。

          8. 聚合

          聚合是關聯的特例。在兩個對象之間的關系中,一個對象可能比另一個更重要。換句話說,當一個對象比另一個擁有更多的所有權時,這就是聚合。對象所有者通常稱為聚合,被所有者稱為組件。聚合又叫“Has-a”關系。

          functionBook(title, author) {

          this.title=title;
          this.author=author;
          }

          const book1=new Book ('Hippie', 'Paulo Coelho');

          const book2=new Book ('TheAlchemist', 'Paulo Coelho');

          let publication={
          "name": "new publicationInc",
          "books": []
          }publication.books.push(book1);
          publication.books.push(book2);

          book1 和 book2 被添加到對象publication下設的books中。如果在book1和book2 運行之后刪除publication,則 Book和 publication 都將獨立運行。

          9. 組合

          組合是聚合的一種特殊情況。一個對象包含另一個對象,并且被包含的對象脫離后無法生存。

          let Book={

          "title": "TheAlchemist",
          "author": "PauloCoelho",
          "publication": {
          "name": "newpublication Inc",
          "address":"chennai"
          }
          }

          這里屬性publication與 Book 對象有嚴格的限制,publication不能沒有Book對象。如果Book的id被刪除,則publication也將被刪除。

          重組合輕繼承

          繼承指一個對象基于另一個對象的情況。例如,book1繼承了標題、作者和結語等書籍的屬性和方法,所以它建立了book1 is-a Book關系。

          組合是收集單一對象并將它們組合起來構建更復雜的對象。為構建book1,需要一些方法,比如紙和筆。因此book1 has-a paper and a pen關系隨之出現。

          constgetTitle=(data)=> ({

          title : ()=> console.log(`title :${data.title}`)
          });const getAuthor=(data)=> ({
          author : ()=> console.log(`author:${data.author}`)
          });const getSummary=()=> ({
          summary :()=> console.log(`booksummary need to

          update.`)
          });const Book=(title, author)=> {
          const data={
          title,
          author
          }
          return Object.assign({},
          getTitle(data),
          getAuthor(data),
          getSummary()
          )
          }let book1=Book('The Alchemist', 'Paulo Coelho');

          book1.title();
          > "title : The Alchemist"

          留言點贊關注

          我們一起分享AI學習與發展的干貨

          如轉載,請后臺留言,遵守轉載規范

          程序員前端教程-javascript的面向對象

          一、什么是面向對象?

          1.面向對象就是把構成問題是無分解成多個對象,建立對象不是為了完成某個步驟,而是描述某個事物在這個解決問題的步驟中的行為。

          2.面向對象是一種思維方法。

          3·面向對象是一種編程方法。

          4·面向對象并不只針對某一種編程語言。

          二、面向對象和面向過程的區別和聯系?

          1.面向過程側重整個問題的解決步驟,著眼局部或者具體。

          2·面向對象側重具體的功能,讓某個對象具有這樣的功能,更側重整體。

          面向過程的優點:

          1.流程化使得編程任務明確,在開發之前基本考慮實現的方法和最終結果;

          2.效率高,面向過程強調代碼的短小精悍,善于結合數據結構來開發高效率程序;

          3.流程明確,具體步驟清楚,便于節點分析。

          面向過程的缺點:

          1.需要深入的思考,耗費精力,代碼重用性低,擴展能力差,維護起來難度比較高。

          2.對復雜業務來說,面向過程的模塊難度較高,耦合度也比較高。

          面向對象的優點:

          1.結構清晰,程序便于模塊化,結構化,抽象化,更加符合人類的思維方式;

          2.封裝性,將事務高度抽象,從而便于流程中的行為分析,也便于操作和自省;

          3.容易擴展,代碼重用率高,可繼承,可覆蓋;

          4.實現簡單,可有效地減少程序的維護工作量,軟件開發效率高。?

          面向對象的缺點是:

          1.效率低,面向對象在面向過程的基礎上高度抽象,從而和代碼底層的直接交互非常少機會,從而不適合底層開發和游戲甚至多媒體開發。

          2.復雜性,對于事務開發而言,事務本身是面向過程的,過度的封裝導致事務本身的復雜性提高。

          三、面向對象的實現方式

          1.面向對象的實現方式主流有兩種方式:基于類的面向對象和基于原型的面向對象。

          2.面向對象三大特征:封裝、繼承、多態。

          3.基于類的面向對象:Java、C#對象(object)依靠類(class)來產生。

          4.基于原型的面向對象:javascript對象(object)依靠構造器(constructor)利用原型(prototype)構造出來的。

          四、多種創建對象的方式

          基礎封裝、工廠模式、構造函數、原型對象、組合創建。


          主站蜘蛛池模板: 嫩B人妻精品一区二区三区| 蜜桃传媒视频麻豆第一区| 亚洲AV乱码一区二区三区林ゆな | 国产精品亚洲一区二区麻豆| 人妻少妇精品一区二区三区| 免费萌白酱国产一区二区三区| 亚洲第一区精品日韩在线播放| 精品一区二区三区电影| 国产激情无码一区二区三区| 国产亚洲3p无码一区二区| 国产乱码一区二区三区四| 在线免费一区二区| 日韩精品一区二三区中文| 国产精品无码一区二区三区电影| 日韩精品无码一区二区中文字幕| 成人区精品一区二区不卡亚洲 | 久久福利一区二区| 亚洲欧美日韩中文字幕一区二区三区| 无码一区二区三区AV免费| 国产伦精品一区二区三区四区| 一区二区三区无码高清视频| 日产精品久久久一区二区| 国产伦精品一区二区| 无码乱人伦一区二区亚洲一| 成人精品一区二区三区电影| 国产品无码一区二区三区在线蜜桃| 中文字幕av一区| 国产在线无码视频一区二区三区| 一区二区国产精品| 中文字幕一区日韩精品| 成人乱码一区二区三区av| 人妻精品无码一区二区三区| 国产午夜精品一区二区三区不卡| 色欲AV蜜桃一区二区三| 中文字幕乱码一区二区免费| 日本一区二区三区日本免费| 日韩一区二区在线观看视频| 国产AⅤ精品一区二区三区久久| 久久毛片一区二区| 红桃AV一区二区三区在线无码AV| 怡红院一区二区在线观看|