在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...