JavaScript 是一門集成了函數編程和麪向對象編程的動態語言。它的對象是一個容器,封裝了屬性(property)和方法(method)。JavaScript的面向對象實現不是基於類,而是基於構造函數(constructor)和原型鏈(prototype)實現的。
一.繼承概述
- 本文主要介紹了原型對象,prototype 屬性,原型鏈,constructor 屬性。
- 原型對象介紹? 使用構造函數創建對象實例的時候,系統會維護一個原型對象,構造函數的
prototype
屬性指向此對象,此對象的所有屬性和方法都會被所有實例共享。實例無prototype
屬性,打印出是undefined
。具體見: 原型對象概述 - 原型鏈介紹? 構造函數中的
prototype
屬性原型對象指向自己,若無其它繼承關係其的原型對象就指向Object
,Object
原型對象指向null
。具體見: 原型鏈 - 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中的valueOf
和toString
方法。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"