ES5和ES6及繼承機制

2021-08-30 11:06:39 字數 4086 閱讀 7931

這幾天在學習react的時候學習到es6的class extends繼承方式,就複習一下es5的繼承機制,並整理下來。

在js萬物皆物件,但事還是區分普通物件和函式物件,那大家需要知道是只有函式物件才有prototype屬性,但所有物件都有__proto__屬性

function a(

)var b = new a;

那這裡就得出幾個公式:

b.__proto__== a.prototype; 

b.constructor == a;

a.prototype.constuctor = a;

那這是實現繼承的基礎;

也就是說a.prototype是a的原型物件,a是建構函式,b是a的例項,原型物件(a.prototype)是 建構函式(a)的乙個例項。而此時this指向是指向例項。

明白這個關係實現繼承就很簡單了!看一下下面的**

通過重寫子類的原型 等於 父類的乙個例項,(父類的例項屬相變成子類的原型屬性)

function father(

)father.prototype.getfaname = function();

function child(

)child.prototype = new father();

child.prototype.constructor = child;

child.prototype.getchname = function(

);

通過子類的原型物件指向父類例項的方式來實現繼承,那我們不難發現原型鏈的形成是真正是靠__proto_ 而非prototype,子類的例項可以訪問父類原型上的方法,是因為子類例項通過 _proto 與父類的原型物件有連線

//先來個父類,帶些屬性

function super(

)//為了提高復用性,方法繫結在父類原型屬性上

super.prototype.getflag = function(

)//來個子類

function sub(

)//實現繼承

sub.prototype = new super;

//給子類新增子類特有的方法,注意順序要在繼承之後

sub.prototype.getsubflag = function(

)//構造例項

var es5 = new sub;

所謂寄生組合式繼承,即通過借助建構函式來繼承屬性,通過原型鏈的混成形式來繼承方法。

其背後的基本思路是:不必為了指定子型別的原型而呼叫超型別的建構函式,我們所需要的無非就是超型別原型的乙個副本而已。本質上,就是使用寄生式繼承來繼承超型別的原型,然後再將結果指定給子型別的原型。

function inserit(son, father)

function supertype(name,colors)

supertype.prototype.sayname = function (

)function subtype(job,name,color)

//核心方法

inserit(subtype, supertype)

;subtype.prototype.sayjob = function (

)var instance= new subtype(

"doctor"

,"john",[

"red"

,"green"])

;console.log(instance.sayjob(

),instance.sayname())

//doctor,john

class

point

print()

}point.prototype.z =

'4'class

colorpoint extends point

m()}

es6繼承是通過classextends關鍵字來實現繼承 point是父類,colorpoint 是子類 通過 class 新建子類 extends繼承父類的方式實現繼承,方式比es5簡單的多。

constructor 方法是類的建構函式,是乙個預設方法,通過 new 命令建立物件例項時,自動呼叫該方法。乙個類必須有 constructor 方法,如果沒有顯式定義,乙個預設的 consructor 方法會被預設新增。所以即使你沒有新增建構函式,也是會有乙個預設的建構函式的。一般 constructor 方法返回例項物件 this ,但是也可以指定 constructor 方法返回乙個全新的物件,讓返回的例項物件不是該類的例項。

class

points

print()

statc getname()}

等同於:

function points(x)

points.prototype.

print

= function(

)

也就是說constructor就代表在父類上加屬性,而在class物件加方法屬性 等於在原型上的加。而這些屬性方法 只有通過new出的例項 或者是extends 繼承出來的例項才可以獲取到 所以我們可以得到

new points(

).__proto__.

print()

//可以呼叫到points的print方法

new points(

).x =

1//可以呼叫到constructor 裡面的 this.x=

1

super既可以當做函式使用,也可以當做物件使用兩種使用的時候完全不一樣,

函式用時: 在 constructor 中必須呼叫 super 方法,因為子類沒有自己的 this 物件,而是繼承父類的 this 物件,然後對其進行加工,而 super 就代表了父類的建構函式。super 雖然代表了父類 a 的建構函式,但是返回的是子類 b 的例項,即 super 內部的 this 指的是 b,因此 super() 在這裡相當於

a.prototype.constructor.call(this, props)
在 super() 執行時,它指向的是 子類 b 的建構函式,而不是父類 a 的建構函式。也就是說,super() 內部的 this 指向的是 b。所以在第乙個es6的例子中子類的this指向的是自己。、

當做物件使用: 在普通方法中,指向父類的原型物件;在靜態方法中,指向父類。

所以在子類的方法中super.print();指向的是父類原型上的方法。

但是因為super的兩種用法,所以es6規定在使用必須要明確使用方式,像單獨console.log(super) 就會報錯。

顧名思義是靜態方法的意思,類相當於例項的原型, 所有在類中定義的方法, 都會被例項繼承。 如果在乙個方法前, 加上static關鍵字, 就表示該方法不會被例項繼承, 而是直接通過類來呼叫, 這就稱為「 靜態方法」。靜態方法呼叫直接在類上進行,而在類的例項上不可被呼叫。靜態方法通常用於建立 實用/工具 函式。

new.target屬性允許你檢測函式或構造方法是否通過是通過new運算子被呼叫的。在通過new運算子被初始化的函式或構造方法中,new.target返回乙個指向構造方法或函式的引用。在普通的函式呼叫中,new.target 的值是undefined。

也就是說new.target的功能就是用來檢測函式的呼叫是不是通過 new 去建立乙個新物件的,而且new.target返回的是乙個指向函式的引用,也就是說我們能夠確定是哪個函式進行了new操作。

先建立父類例項this 通過class丶extends丶super關鍵字定義子類,並改變this指向,super本身是指向父類的建構函式但做函式呼叫後返回的是子類的例項,實際上做了父類.prototype.constructor.call(this),做物件呼叫時指向父類.prototype,從而實現繼承。

ES5和ES6的繼承

在es6之前,js的函式和物件是混在一起的,通過new呼叫函式,就是把函式當作物件,建立例項。funciton person name,age person.prototype.getname function person.prototype.setname function name var p...

ES5和ES6的繼承

建構函式 function obj uname,age 建立例項物件 var test newobj uname 18 使用方法 test.method obj.boy 建構函式名字的首字母要大寫,且與new一起使用 建構函式中的屬性方法被叫做成員。其中 1 靜態成員 在建構函式本身上新增的成員,如...

ES5和ES6的繼承

es5繼承 建構函式 原型和例項的關係 每乙個建構函式都有乙個原型物件,每乙個原型物件都有乙個指向建構函式的指標,而每乙個例項都包含乙個指向原型物件的內部指標,1 function supertype 4 supertype.prototype.getsupervalue function 7 fu...