面向對象的程式設計-2-創建對象

来源:http://www.cnblogs.com/miaowwwww/archive/2017/01/06/6256130.html
-Advertisement-
Play Games

該文為閱讀高級程式設計(第三本)p144-p164的理解與總結! 接受指導與批評。 對於我,我一直是使用字面量的方式創建對象,然而體繫上的創建對象的方法卻並不局限於此。 創建對象的方法 1 工廠模式: 定義工廠函數創建並返回包含特定屬性的對象, 2 構造函數模式: 先貼出代碼 2.1 new Per ...


該文為閱讀高級程式設計(第三本)p144-p164的理解與總結!  接受指導與批評。

對於我,我一直是使用字面量的方式創建對象,然而體繫上的創建對象的方法卻並不局限於此。

創建對象的方法

  1. 工廠模式
  2. 構造函數模式
  3. 原型模式
  4. 組合使用構造模式和原型模式
  5. 動態原型模式
  6. 寄生構造函數模式
  7. 穩妥的構造函數模式

1 工廠模式:

  定義工廠函數創建並返回包含特定屬性的對象, 

function createPerson(name, age, job) {
    var o = new Object();    // var o = {}; //一樣
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var person0 = createPerson('jody', 22, 'wife');

 

2 構造函數模式:

  先貼出代碼

function Person(name) {
    this.name = name;
    this.sayName = function() {
        console.log(this);
    }
}
var person1 = new Person('xxx');
var person2 = new Person('bbb');
console.log(person1)

 

  2.1 new Person() 的發生了什麼?步驟分解:這是重點(new的工作原理)

    1. 新建一個對象: instance = new Object(); 
    2. 設置原型鏈: instance.prototype = Person.prototype 
      1.   任意函數在創建的時候都會創建prototype對象,並自動為它添加constructor屬性
    3. 讓 Person 中的 this 指向 instance, 然後執行函數:
      1.   相當於在instance中定義屬性(name,sayName)
    4. 判斷 Person 函數的返回 :
      1.   Person 中沒有寫return,相當於return undefined(值類型),因此返回instance
      2.   如果返回值類型,則丟棄該值類型, 然後返回 instance。
      3.   如果返回引用類型,則丟棄instance, 返回該引用類型。

  2.2 構造函數也是函數,

    它是可以直接執行的,然後給執行作用域綁定屬性。    

    任何函數,只要使用new 操作符,這個函數函數就變成了構造函數

  2.3 構造函數的優缺點

      1.優點:

person1 instanceof Person
person2 instanceof Object   //都為ture,用於判斷類型(工廠模式不行)

      2.缺點:公共屬性(如sayName)在每一個Person實例中都創建了,不能做到復用

 

3 原型模式

function Person() {
};
Person.prototype.sayName = function() {
    console.log(this.name);
}
Person.prototype.name = 'miaowwwwww';
var person1 = new Person();
var person2 = new Person();
person1.sayName();
console.log(person1)

 

  3.1 什麼是原型對象??

    當創建一個函數的時候,js根據一組特定的規則自動地為函數創建 prototype 屬性 和 一個原型對象。

    prototype 屬性是一個指針,指向原型對象。

    原型對象自動獲得一個 constructor(構造函數) 指針屬性,該屬性指向 被創建的函數。

  3.2 實際應用重點:

        使用構造函數創建的每一個實例,都自動包含一個[[prototype]] 指針屬性。(在瀏覽器prototype是隱藏的,一些瀏覽器提供__proto__)。

        並且這個屬性指向,構造函數的 prototype (即原型對象, 所以每一個實例共用一個原型對象

  3.3 構造函數-原型-實例的關係如圖:

 

 

 

 

 

 

 

 

 

 

   3.4 註意:

    1.  原型對象上的可遍歷屬屬性將會出現在 實例的 for-in 遍歷中  
    2.  構造函數 Person.prototype 是一個指針
      1.   若使用 Person.prototype.sayName = function() {...}  表示在原 原型中添加屬性
      2.   若使用如下方式:表示 改變了 Person.prototype 的指針, 讓它指向了一個新的對象,該對象的屬性被實例共用,當缺失了constructor屬性
        Person.prototype = {
            constructor: Person,    // 可手動添加,補全constructor屬性
            name: 'miaowwwww',
            sayName: function() {
                console.log(this.name);
            }
        }

   3.5 原型模式的優缺點

       1.優點:

      1.   完善構造函數模式的缺點,所有實例可以共用原型的方法,而不需要是個實例創建副本,提高復用性
      2.   類型判斷
person1 instanceOf Person 
Person.isPrototypeOf(person1)
Object.getPrototypeOf(person1) === Person
// 都可以正確判斷結果

 

       2.缺點:若原型中使用引用類型,則實例可以修改原型中的

function Person() {};
Person.prototype = {
    constructor: Person,
    name: 'miaowwwww',
    friends: ['jody', 'robin'],
    sayName: function() {}
}
var person1 = new Person();
var person2 = new Person();
person1.friends.push('mike');
// person2.friends : ['jody', 'robin', 'mike'];

  

 4. 組合構造函數模式與原型模式

function Bird(name) {
    this.name = name;
    this.friends = ['mike', 'jody'];
}
Bird.prototype = {
    sayName: function() {
        console.log(this.name);
    }
}

 

   4.1 優點: 結合構造函數模式與原型模式的優點,把引用類型的屬性,放到構造函數中,為每一個實例創建副本,同時復用原型上的方法

 

5.動態原型模式

function Cat(name) {
    this.name = name;
    this.friends = ['a', 'b'],
    if(typeof this.sayName !== 'function') {
        Cat.prototype.sayName = function() {
            console.log(this.name);
        }
    }
}

  5.1 解讀:就是把第四種模式,變異一下,在判斷實例沒有 sayName 方法的時候才添加 該方法到 原型上

       每次新建對象的時候都會執行判斷代碼, 然後只有第一次執行, if 才為true

 

6.寄生構造函數模式

function Book(name) {
    var o = new Array();
    o.name = name;
    o.sayName = function() {
        console.log(this.name);
    }
    return o;
}
var book1 = new Book('javascript');

 

   6.1 請回顧上面說過的 2.1 new 的工作原理

   6.2 理解:

    1. 這種方法除了 return 以及 new Book()  之外,跟工廠函數基本沒有區別。
    2. 可以理解為對已有對象的增強(如這裡的Array,因為不能直接修改Array對象)

  6.3 缺點:

    1. book1 的原型中不包含 Book, 而是Array, 所以叫寄生
    2. 與構造函數一樣,每一個實例都有 sayName.. 的副本,復用性降低

 7 穩妥的構造函數模式

function Fish(_name){
    var o = new Object(); // new Person(); 或其他對象
    
    // 私有變數和函數
    var name = _name;
    function sayHi() {
        console.log('hi')
    };
    // ...

    // 添加方法
    o.sayName = function() {
        console.log(name);
        sayHi();
        return name;
    }
    o.setName = function(value) {
        name = value;
    }
    return o;
}
var aa = Fish('miaowwwww');
var bb = Fish('jody');
aa.sayName();
bb.sayName();

 

  7.1 這個竟然是平時一直在用的閉包。

  7.2 優點:變數私有化,並且只能通過特定介面訪問

    缺點: 又是每一個實例一個函數副本,復用性降低了;

  

 


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

-Advertisement-
Play Games
更多相關文章
  • 動畫分為: 1.css3動畫:(動畫性能遠高於js) 1).過渡動畫(transition) 2).關鍵幀動畫(@keyframes,animation) 2.js動畫: 過渡動畫(transition) 語法: (所有時長單位都是秒) 1.變化屬性(transition-property(屬性名) ...
  • 本文將介紹一款基於jquery的二維碼生成插件qrcode,在頁面中調用該插件就能生成對應的二維碼。 1、首先在頁面中加入jquery庫文件和qrcode插件。 2、在頁面佈局中添加一個div 3、調用qrcode插件。 4、我們試驗的時候發現不能識別中文內容的二維碼,通過查找多方資料瞭解到,jqu ...
  • html css 第一種方法:.box{clear:box} 第二種方法:.box{overflow:hidden} 第三種方法:.box{overflow:auto} 第四種方法:.box:after{ content:""; height:0; visibility:hidden; displa ...
  • 一、Node.js本質上是js的運行環境。 二、可以解析js代碼(沒有瀏覽器安全級的限制); 提供系統級的API:1、文件的讀寫 2、進程的管理 3、網路通信 三、可以關註的四個網站: 1、https://nodejs.org/en/(官網) 2、https://www.npmjs.com/ 3、h ...
  • 1、背景圖片中部放大、縮小 ...
  • border-image-source 屬性設置邊框的圖片的路徑[none | <image>] border-image-slice 屬性圖片邊框向內偏移[ <number> | <percentage> ](1,4) ?fill border-image-width 屬性設置圖片邊框的寬度[ < ...
  • border-radius 屬性設置邊框的園角 可能的值:像素,百分比 擴展延伸 html代碼 css代碼 結果 css代碼 結果 css代碼 結果 css代碼 結果 css代碼 結果 css代碼 結果 css代碼 結果 ...
  • 函數本身就是一段JavaScript代碼,定義一次但可能被調用任意次。如果函數掛載在一個對象上,作為對象的一個屬性,通常這種函數被稱作對象的方法。用於初始化一個新創建的對象的函數被稱作構造函數。 相對於其他面向對象語言,在JavaScript中的函數是特殊的,函數即是對象。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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...