在React中如何判斷元件是函式還是類

2021-10-05 07:52:03 字數 3302 閱讀 1856

在react中,支援使用class和function來宣告乙個元件,而實際上,我們在使用這個元件時,因為class和function的不同,所以我們的使用也存在不同

我們知道,function是可以直接呼叫的,但是class是需要通過new去建立乙個例項來使用的

function

// 你的**

function

greeting()

// react 內部

const result =

greeting

(props)

;// hello

class

// 你的**

class

greeting

extends

react.component

}// react 內部

const instance =

newgreeting

(props)

;// greeting {}

const result = instance.

render()

;// hello

雖然使用時不一樣,但實際上我們的目標都是去獲取渲染後的節點

首先,理解為什麼要將function和class區分開很重要,我們需要先理解new的使用,下面是我自己實現的乙個new

function

_new

(c,...args)

is not a constructor`)}

let obj = object.

create

(c.prototype)

let res = c.

call

(obj,

...args)

return

typeof res ===

"object"

?res:obj

}

我們知道,new是通過建立乙個新的物件,然後將方法中的this繫結在這個物件上,然後執行方法,如果方法返回的是原始型別,那麼就返回新建立的這個物件,如果返回的是乙個引用型別諸如物件和陣列,那麼就會返回這個引用型別

實際上,如果我們允許不採用new來呼叫乙個類,那麼很可能導致的結果是,建立的新例項的this會指向undefined或者window,甚至會建立了window.name這種屬性

而我們也要清楚,當我們在使用react的時候,實際上經常會用到babel進行乙個編譯的操作,而在babel中,雖然早期類不加new也可以被呼叫,但現在已經被修復了,通過新增了額外的**來實現修復

function

person

(name)

// our code:

this

.name = name;

}new

person

('fred');

// ✅ ok

person

('george');

// ? 無法把類當做函式來呼叫

那麼,現在的問題在於,我們在使用class的時候需要使用new去呼叫,而使用function不用,雖然在js裡面我們可以對class和function進行乙個區分,但是對於babel編譯後的類,在瀏覽器看來,它和function只是不同的函式。

雖然即使是常規函式,我們通過new來進行乙個呼叫也不會有問題。在沒有class之前我們也會採用function來模擬乙個類,但實際上,函式元件是不可取的

我們可以看以下兩個理由

首先,箭頭函式,我們知道,箭頭函式本身沒有自己的this,箭頭函式內部的this,指向了箭頭函式所在的那個作用域的this,因此,我們無法對乙個箭頭函式使用new來構造,而函式元件卻是允許我們採用箭頭函式

此外,上面已經提到過,new在使用時,本身函式如果返回了乙個原始型別的話,最終會返回的是乙個新建立的物件,而我們在使用函式元件的時候,有的時候是會返回乙個純文字的,因此直接新增乙個new,會使得我們無法直接返回乙個純文字

看過別人的部落格,才理解到,實際上上面我們考慮的,是對於所有的函式和類,去做乙個判斷區分,這是乙個籠統的問題,但實際上,我們是可以去解決乙個具體的問題,區分乙個元件是class或者function

如何去區分,我們可以想到的是,當我們使用function的時候,我們是直接宣告乙個function,那,我們使用class的時候呢,會去繼承乙個react.component

看到繼承我想你應該有思路了,我們可以通過判斷原型鏈上是否有react.component去判斷我們用了class還是function

談到原型鏈,我們可以先看看下面這段**

class

aclass

bextends

aconsole.

log(

b.prototype instanceofa)

;// true

這段**咋一看,好像沒什麼問題,但仔細想想,class b extends a {}這段**,是什麼繼承了a,是b這個類嗎?不是啊,是b的例項,那麼為什麼,b.prototype instanceof a會返回true,這裡就要扯一下__proto__和prototype了

首先有乙個問題,下面這段**,會列印什麼

function

person()

console.

log(person.prototype === person.__proto__)

console.

log(person.prototype ===

newperson()

.__proto__)

答案是false true

這裡就說明了person.prototype實際上指的不是person的原型(我感覺這個誤導了很多人),而是指向了它建立的例項的原型,當然,如果這裡的person返回了乙個引用型別的話,那第二個console也會返回乙個false

通過上面的**和描述,我們也明白了,原型鏈實際上,更像是obj.proto.proto.__proto__這種形式

知道原型鏈的繼承方式後,我們來看看class的extends,看起來似乎是一種新的繼承方式,但實際上,還是基於原型鏈實現的繼承,因此,我們可以通過原型鏈,來判斷乙個元件function還是class

方便的是,instanceof就是通過原型鏈來進行型別判斷的,因此我們可以直接採用instanceof來進行判斷

然而react並不是這麼做的,具體可見

typescript在react元件中的使用

typescript中文文件 布林值 let istrue boolean false 數字 let num number 4 字串 let name string boble 陣列 let arr number 1,2,3,4 let arrs array 注意 內部表示陣列item的屬性,可以設...

react 元件復用判斷div在左邊還是右邊

父元件 父元件裡面無需定義isright,只需要在傳遞乙個isright給子元件,其他沒傳遞的是預設為true 子元件接收 用props接收 右邊div function rightbox src div function classfiybox props props return 如果!isri...

react中如何編寫元件的樣式

注意點 使用於所有的元件樣式,react中規定,寫行內樣式時,要寫在 中,使用駝峰命名發 這是行內樣式 div 使用.css樣式 使用.less樣式 使用.scss樣式 在需要的元件內,使用import 外聯樣式表相對路徑 語法匯入外聯的樣式表 使用classname屬性 將class用classn...