JavaScript 面向對象編程繼承上【三】(原型對象,prototype 屬性,原型鏈,constructor 屬性)

JavaScript 是一門集成了函數編程和麪向對象編程的動態語言。它的對象是一個容器,封裝了屬性(property)和方法(method)。JavaScript的面向對象實現不是基於類,而是基於構造函數(constructor)和原型鏈(prototype)實現的。

一.繼承概述

  1. 本文主要介紹了原型對象,prototype 屬性,原型鏈,constructor 屬性。
  2. 原型對象介紹? 使用構造函數創建對象實例的時候,系統會維護一個原型對象,構造函數的prototype屬性指向此對象,此對象的所有屬性和方法都會被所有實例共享。實例無prototype屬性,打印出是undefined具體見: 原型對象概述
  3. 原型鏈介紹? 構造函數中的prototype屬性原型對象指向自己,若無其它繼承關係其的原型對象就指向ObjectObject原型對象指向null具體見: 原型鏈
  4. constructor屬性定義在哪裏?有什麼作用? constructor屬性定義在prototype對象中,默認指向prototype對象所在的構造函數。其的作用是標明某個實例對象,是哪一個構造函數產生的。

二.原型對象的概述

1.原型對象概述

  • 使用構造函數創建的實例之間是無法共享屬性的,所以需要JavaScript 的原型對象(prototype)來共享實例。
  • 原型對象,就是定義所有實例對象共享的屬性和方法。而實例對象可以視作從原型對象衍生出來的子對象。使用這種方式實現繼承。

2.prototype 屬性的作用

  • 設計思想:JavaScript 繼承機制的設計思想就是,原型對象的所有屬性和方法,都能被實例對象共享。

    function f() {}
    typeof f.prototype // "object"
    
  • 定義:JavaScript 規定,每個函數都有一個prototype屬性,指向一個對象。 對於普通函數來說,該屬性基本無用。但是,對於構造函數來說,生成實例的時候,該屬性會自動成爲實例對象的原型

    //爲原型對象添加一個color,所有實例共享此屬性
    function Animal(name) {
      this.name = name;
    }
    Animal.prototype.color = 'white';
    
    var cat1 = new Animal('lip');
    var cat2 = new Animal('tom');
    
    cat1.color // 'white'
    cat2.color // 'white'
    
  • 特性: 原型對象的屬性不是實例對象自身的屬性。只要修改原型對象,變動就立刻會體現在所有實例對象上。 讀取對象的某個屬性時,JavaScript 引擎先尋找對象本身的屬性,如果找不到,就到它的原型去找,如果還是找不到,就到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回undefined。 如果對象自身和它的原型,都定義了一個同名屬性,那麼優先讀取對象自身的屬性,這叫做“覆蓋”(overriding)。

    //一. 屬性共享
    //原型定義屬性
    Animal.prototype.color = 'yellow';
    
    cat1.color // "yellow"
    cat2.color // "yellow"
    //原型定義方法
    Animal.prototype.walk = function () {
      console.log(this.name + ' is walking');
    };
    
    //二. 實例中定義相同屬性,將不再獲取原型中的屬性
    cat1.color = 'black';
    
    cat1.color // 'black'
    cat2.color // 'yellow'
    Animal.prototype.color // 'yellow';
    

三.原型鏈

1.原型鏈概述

  • JavaScript 規定,所有對象都有自己的原型對象(prototype)。相應的原型對象也將有自己的原型對象,這樣就形成了“原型鏈”(prototype chain)。

2.原型鏈的繼承關係

  • 構造函數prototype指向的對象原型是本身對象,若無其他繼承關係,則對象的頂層原型是Object.prototype,所有對象都繼承了Object中的valueOftoString方法。Object.prototype的原型是null,其沒有任何屬性和方法,原型鏈的盡頭就是null

    //一. Animal的原型對象是Animal
    Animal.prototype//Animal
    //二. 返回Animal原型對象的原型對象是Object
    var pr =   Object.getPrototypeOf(Animal.prototype);//Object
    //三. Object.prototype對象的原型是null,由於null沒有任何屬性,所以原型鏈到此爲止。Object.getPrototypeOf方法返回參數對象的原型
    Object.getPrototypeOf(Object.prototype)
    // null
    

四.prototype對象的constructor 屬性

1.constructor介紹

  • prototype對象有一個constructor屬性,默認指向prototype對象所在的構造函數。constructor屬性,可以被此原型對象的所有子類繼承。

    //一. 原型對象中的prototype函數指向構造函數
    function P() {}
    P.prototype.constructor === P // true
    
    //二. 可被所有實例繼承
    function P() {}
    var p = new P();
    
    p.constructor === P // true
    p.constructor === P.prototype.constructor // true
    p.hasOwnProperty('constructor') // false
    

2.constructor作用

  • constructor作用是標明實例生成的構造函數。描述了原型對象與構造函數之間的關聯關係

    function F() {};
    var f = new F();
    
    f.constructor === F // true
    f.constructor === RegExp // false
    
  • 獲取構造函數的名稱

    function Foo() {}
    var f = new Foo();
    f.constructor.name // "Foo"
    
發佈了181 篇原創文章 · 獲贊 65 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章