React學(xué)習(xí)之漫談React

  • 事件系統(tǒng)

  1. 合成事件的綁定方式
    <button onClick={this.handleClick}>Test</button>
  2. 合成事件的實(shí)現(xiàn)機(jī)制:事件委派和自動綁定。
  3. React合成事件系統(tǒng)的委托機(jī)制,在合成事件內(nèi)部僅僅是對最外層的容器進(jìn)行了綁定,并且依賴事件的冒泡機(jī)制完成了委派。
  • 表單

  1. React受控組件更新state的流程:
  2. 可以通過在初始state中設(shè)置表單的默認(rèn)值跑芳。
  3. 每當(dāng)表單的值發(fā)生變化時(shí),調(diào)用onChange事件處理器直颅。
  4. 事件處理器通過合成事件對象e拿到改變后的狀態(tài)博个,并更新應(yīng)用的state。
  5. setState觸發(fā)視圖的重新渲染际乘,完成表單組件值的更新坡倔。
  6. 受控組件和非受控組件的最大區(qū)別是:非受控組件的狀態(tài)并不會受應(yīng)用狀態(tài)的控制漂佩,應(yīng)用中也多了局部組件狀態(tài)脖含,而受控組件的值來自于組件的state。
  • 樣式處理

  1. CSS模塊化遇到了哪些問題投蝉?全局污染养葵,命名混亂,依賴管理不徹底瘩缆,無法共享變量关拒,代碼壓縮不徹底。
  2. CSS Modules模塊化方案:啟用CSS Modules庸娱,樣式默認(rèn)局部着绊,使用composes來組合樣式。
  • 組件間通信

  1. 子組件向父組件通信
  2. 利用回調(diào)函數(shù)
  3. 利用自定義事件機(jī)制
  4. 當(dāng)需要讓子組件跨級訪問信息時(shí)熟尉,我們還可以使用context來實(shí)現(xiàn)跨級父子組件間的通信归露。
  5. 沒有嵌套關(guān)系的組件通信:我們在處理事件的過程中需要注意,在componentDidMount事件中斤儿,如果組件掛載完成剧包,再訂閱事件;當(dāng)組件卸載的時(shí)候往果,在componentWillUnmount事件中取消事件的訂閱疆液。
  • 組件間抽象

  1. mixin 的目的,就是為了創(chuàng)造一種類似多重繼承的效果陕贮,或者說堕油,組合。實(shí)際上,包括C++等一些年齡較大的OOP語言掉缺,都有一個(gè)強(qiáng)大但是危險(xiǎn)的多重繼承特性「R玻現(xiàn)代語言權(quán)衡利弊,大都舍棄了它攀圈,只采用單繼承暴凑。但是單繼承在實(shí)現(xiàn)抽象的時(shí)候有很多不便,為了彌補(bǔ)缺失赘来,Java引入接口(interface)现喳,其他一些語言則引入了mixin的技巧。
    封裝mixin方法
    方法:
const mixin = function(obj, mixins) {
    const newObj = obj;
    newObj.prototype = Object.create(obj.prototype);
    for (let prop in mixins) {
        if (mixins.hasOwnProperty(prop)) {
            newObj.prototype[prop] = mixins[prop]; 
        }
    }
    return newObj; 
}

應(yīng)用:

const BigMixin = { 
    fly: () ={
        console.log('I can fly'); 
    }
};
const Big = function() { 
    console.log('new big');
};
const FlyBig = mixin(Big, BigMixin);
const flyBig = new FlyBig(); // ='new big'
flyBig.fly(); // ='I can fly'

上面這段代碼實(shí)現(xiàn)對象混入的方法是:用賦值的方式將mixin對象里的方法都掛載到原對象上犬辰。

  1. 在React中使用mixin
    React在使用createClass構(gòu)建組件時(shí)提供了mixin屬性嗦篱,比如官方封裝的:PureRenderMixin。
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
React.createClass({
    mixins: [PureRenderMixin],
    render() {
        return <div>foo</div>;
    }
});

在createClass對象參數(shù)中傳入數(shù)組mixins幌缝,里面封裝了我們需要的模塊灸促。mixins數(shù)組也可以添加多個(gè)mixin。同時(shí)涵卵,在React中不允許出現(xiàn)重名普通方法的mixin浴栽。而如果是生命周期方法,則React將會將各個(gè)模塊的生命周期方法疊加在一起然后順序執(zhí)行轿偎。
使用createClass實(shí)現(xiàn)的mixin為組件做了兩件事:

  1. 工具方法:這是mixin的基本功能典鸡,如果希望共享一些工具類的方法,就可以直接定義它們?nèi)缓笤诮M件中使用坏晦。
  2. 生命周期繼承萝玷,props和state合并。mixin能夠合并生命周期方法昆婿。如果有很多mixin來定義componentDidMount這個(gè)周期生宛,那么React會很機(jī)智的將它們都合并起來執(zhí)行妄田。同樣,mixin也可以作state和props的合并。
  3. ES6 Classes和decorator
    然而创淡,當(dāng)我們使用ES6 classes的形式構(gòu)建組件的時(shí)候粥谬,卻并不支持mixin宙地。為了使用這個(gè)強(qiáng)大的功能送漠,我們還需要采取其他方法,來達(dá)到模塊重用的目的狼荞×勺埃可以使用ES7的語法糖decorator來實(shí)現(xiàn)class上的mixin。core-decorators庫為開發(fā)者提供了一些實(shí)用的decorator, 其中也正好實(shí)現(xiàn)了我們想要的@mixin相味。
import React, { Component } from 'React'; 
import { mixin } from 'core-decorators';
const PureRender = { 
    shouldComponentUpdate() {}
};
const Theme = { 
    setTheme() {}
};
@mixin(PureRender, Theme)
class MyComponent extends Component {
    render() {} 
}

mixin的問題

  1. 破壞了原有組件的封裝:mixin會混入方法拾积,給原有的組件帶來新特性。但同時(shí)它也可能帶來新的state和props,這意味著組件有一些“不可見”的狀態(tài)需要我們?nèi)ゾS護(hù)拓巧。另外斯碌,mixin也有可能去依賴其他的mixin,這樣會建立一個(gè)mixin的依賴鏈肛度,當(dāng)我們改動一個(gè)mixin的狀態(tài)傻唾,很有可能也會影響其他的mixin。
  2. 命名沖突
  3. 增加復(fù)雜性
    針對這些困擾承耿,React提出的新的方式來取代mixin冠骄,那就是高階組件。
  4. 高階組件
    如果已經(jīng)理解高階函數(shù)加袋,那么理解高階組件也很容易的凛辣。高階函數(shù):就是一種這樣的函數(shù),它接受函數(shù)作為參數(shù)輸入职烧,或者將一個(gè)函數(shù)作為返回值扁誓。例如我們常見的方法map, reduce, sort等都是高階函數(shù)。高階組件和和高階函數(shù)很類似蚀之,高階組件就是接受一個(gè)React組件作為參數(shù)輸入蝗敢,輸出一個(gè)新的React組件。高階組件讓我們的代碼更具有復(fù)用性恬总、邏輯性與抽象性前普,它可以對render方法作劫持,也可以控制props和state壹堰。
    實(shí)現(xiàn)高階組件的方法有如下兩種:
  5. 屬性代理:高階組件通過被包裹的React組件來操作props。
  6. 反向繼承:高階組件繼承于被包裹的React組件骡湖。
    屬性代理
    示例代碼:
import React, { Component } from 'React';
const MyContainer = (WrappedComponent) =
    class extends Component {
        render() {
            return <WrappedComponent {...this.props} />;
        } 
    }

在代碼中我們可以看到贱纠,render方法返回了傳入的WrappedComponent組件。這樣响蕴,我們就可以通過高階組件來傳遞props谆焊。這種方式就是屬性代理。
如何使用上面這個(gè)高階組件:

import React, { Component } from 'React';
class MyComponent extends Component { 
    // ...
}
export default MyContainer(MyComponent);

這樣組件就可以一層層的作為參數(shù)被調(diào)用浦夷,原始組件久具備了高階組件對它的修飾辖试。這樣,保持單個(gè)組件封裝的同時(shí)也保留了易用行劈狐。
從功能上罐孝, 高階組件一樣可以做到像mixin對組件的控制:

  1. 控制props
    我們可以讀取、增加肥缔、編輯或是移除從WrappedComponent傳進(jìn)來的props莲兢。
    例如:新增props
import React, { Component } from 'React';
const MyContainer = (WrappedComponent) =
    class extends Component {
        render() {
            const newProps = {  text: newText, };
            return <WrappedComponent {...this.props} {...newProps} />; 
        }
    }

注意:

<WrappedComponent {...this.props}/>
// is equivalent to
React.createElement(WrappedComponent, this.props, null)

這樣,當(dāng)調(diào)用高階組件的時(shí)候,就可以使用text這個(gè)新的props了改艇。

  1. 通過refs使用引用
  2. 抽象state
    高階組件可以講原組件抽象為展示型組件收班,分離內(nèi)部狀態(tài)。
const MyContainer = (WrappedComponent) =
    class extends Component {
        constructor(props) { 
            super(props); 
            this.state = { name: '', 4 };
            this.onNameChange = this.onNameChange.bind(this); 
        }

        onNameChange(event) { 
            this.setState({
                name: event.target.value, 
            })
        }
        render() {
            const newProps = {
                name: {
                    value: this.state.name, 
                    onChange: this.onNameChange,
                }, 
            }
            return <WrappedComponent {...this.props} {...newProps} />; 
        }
    }

在這個(gè)例子中谒兄,我們把組件中對name prop 的onChange方法提取到高階組件中摔桦,這樣就有效的抽象了同樣的state操作。
使用方式

@MyContainer
class MyComponent extends Component {
    render() {
        return <input name="name" {...this.props.name} />;
    } 
}

反向繼承

const MyContainer = (WrappedComponent) =
   class extends WrappedComponent {
        render() {
            return super.render();
        } 
    }
  • 組件性能優(yōu)化

性能優(yōu)化的思路

影響網(wǎng)頁性能最大的因素是瀏覽器的重排(repaint)和重繪(reflow)承疲。React的Virtual DOM就是盡可能地減少瀏覽器的重排和重繪酣溃。從React渲染過程來看,如何防止不必要的渲染是解決問題的關(guān)鍵纪隙。

性能優(yōu)化的具體辦法

  1. 盡量多使用無狀態(tài)函數(shù)構(gòu)建組件
    無狀態(tài)組件只有props和context兩個(gè)參數(shù)赊豌。它不存在state,沒有生命周期方法绵咱,組件本身即有狀態(tài)組件構(gòu)建方法中的render方法碘饼。在合適的情況下,都應(yīng)該必須使用無狀態(tài)組件悲伶。無狀態(tài)組件不會像React.createClass和ES6 class會在調(diào)用時(shí)創(chuàng)建新實(shí)例艾恼,它創(chuàng)建時(shí)始終保持了一個(gè)實(shí)例,避免了不必要的檢查和內(nèi)存分配麸锉,做到了內(nèi)部優(yōu)化钠绍。
  2. 拆分組件為子組件,對組件做更細(xì)粒度的控制
相關(guān)重要概念:純函數(shù)

純函數(shù)的三大構(gòu)成原則:

  • 給定相同的輸入花沉,它總是返回相同的輸出: 比如反例有 Math.random(), New Date();
  • 過程沒有副作用:即不能改變外部狀態(tài);
  • 沒有額外的狀態(tài)依賴:即方法內(nèi)部的狀態(tài)都只能在方法的生命周期內(nèi)存活柳爽,這意味著不能在方法內(nèi)使用共享的變量。
    純函數(shù)非常方便進(jìn)行方法級別的測試及重構(gòu)碱屁,它可以讓程序具有良好的擴(kuò)展性及適應(yīng)性磷脯。純函數(shù)是函數(shù)式變成的基礎(chǔ)。React組件本身就是純函數(shù)娩脾,即傳入指定props得到一定的Virtual DOM赵誓,整個(gè)過程都是可預(yù)測的。
具體辦法

拆分組件為子組件柿赊,對組件做更細(xì)粒度的控制俩功。保持純凈狀態(tài),可以讓方法或組件更加專注(focus)碰声,體積更小(small)诡蜓,更獨(dú)立(independent),更具有復(fù)用性(reusability)和可測試性(testability)奥邮。

  1. 運(yùn)用PureRender万牺,對變更做出最少的渲染
相關(guān)重要概念: PureRender

PureRender的Pure即是指滿足純函數(shù)的條件罗珍,即組件被相同的props和state渲染會得到相同的結(jié)果。在React中實(shí)現(xiàn)PureRender需要重新實(shí)現(xiàn)shouldComponentUpdate生命周期方法脚粟。shouldComponentUpdate是一個(gè)特別的方法覆旱,它接收需要更新的props和state,其本質(zhì)是用來進(jìn)行正確的組件渲染核无。當(dāng)其返回false的時(shí)候扣唱,不再向下執(zhí)行生命周期方法;當(dāng)其返回true時(shí)团南,繼續(xù)向下執(zhí)行噪沙。組件在初始化過程中會渲染一個(gè)樹狀結(jié)構(gòu),當(dāng)父節(jié)點(diǎn)props改變的時(shí)候吐根,在理想情況下只需渲染一條鏈路上有關(guān)props改變的節(jié)點(diǎn)即可正歼;但是,在默認(rèn)情況下shouldComponentUpdate方法返回true,React會重新渲染所有的節(jié)點(diǎn)拷橘。
有一些官方插件實(shí)現(xiàn)了對shouldComponentUpdate的重寫局义,然后自己也可以做一些代碼的優(yōu)化來運(yùn)用PureRender。

具體辦法
  1. 運(yùn)用PureRender
    使用官方插件react-addons-pure-render-mixin實(shí)現(xiàn)對shouldComponentUpdate的重寫
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }
  render() {
    return <div className={this.props.className}>foo</div>
  }
}

它的原理是對object(包括props和state)做淺比較冗疮,即引用比較萄唇,非值比較。比如只用關(guān)注props中每一個(gè)是否全等(如果是prop是一個(gè)對象那就是只比較了地址术幔,地址一樣就算是一樣了)另萤,而不用深入比較。

  1. 優(yōu)化PureRender
    避免無論如何都會觸發(fā)shouldComponentUpdate返回true的代碼寫法诅挑。避免直接為prop設(shè)置字面量的數(shù)組和對象,就算每次傳入的數(shù)組或?qū)ο蟮闹禌]有變四敞,但它們的地址也發(fā)生了變化。
    如以下寫法每次渲染時(shí)style都是新對象都會觸發(fā)shouldComponentUpdate為true:
<Account style={color: 'black'} />

改進(jìn)辦法:將字面量設(shè)置為一個(gè)引用:

const defaultStyle = {};
<Account style={this.props.style || defaultStyle} />

避免每次都綁定事件,如果這樣綁定事件的話每次都要生成一個(gè)新的onChange屬性的值:

render() {
  return <input onChange={this.handleChange.bind(this)} />
}

該盡量在構(gòu)造函數(shù)內(nèi)進(jìn)行綁定揍障,如果綁定需要傳參那么應(yīng)該考慮抽象子組件或改變現(xiàn)有數(shù)據(jù)結(jié)構(gòu):

constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
}
handleChange() {
  ...
}
render() {
  return <input onChange={this.handleChange} />
}

在設(shè)置子組件的時(shí)候要在父組件級別重寫shouldComponentUpdate目养。

  1. 運(yùn)用immutable
    JavaScript中對象一般是可變的,因?yàn)槭褂靡觅x值毒嫡,新的對象的改變將影響原始對象。為了解決這個(gè)問題是使用深拷貝或者淺拷貝幻梯,但這樣做又造成了CPU和內(nèi)存的浪費(fèi)兜畸。Immutable data很好地解決了這個(gè)問題。Immutable data就是一旦創(chuàng)建碘梢,就不能再更改的數(shù)據(jù)咬摇。對Immutable對象進(jìn)行修改、添加或刪除操作煞躬,都會返回一個(gè)新的Immutable對象肛鹏。Immutable實(shí)現(xiàn)的原理是持久化的數(shù)據(jù)結(jié)構(gòu)逸邦。即使用舊數(shù)據(jù)創(chuàng)建新數(shù)據(jù)時(shí),保證新舊數(shù)據(jù)同時(shí)可用且不變在扰。同時(shí)為了避免深拷貝帶來的性能損耗缕减,Immutable使用了結(jié)構(gòu)共享(structural sharing),即如果對象樹中一個(gè)節(jié)點(diǎn)發(fā)生變化,只修改這個(gè)節(jié)點(diǎn)和受它影響的父節(jié)點(diǎn)芒珠,其他節(jié)點(diǎn)則進(jìn)行共享桥狡。
  • 自動化測試

jest 是 facebook 開源的,用來進(jìn)行單元測試的框架皱卓,功能比較全面裹芝,測試、斷言娜汁、覆蓋率它都可以嫂易,另外還提供了快照功能。
對測試群眾來說掐禁,從質(zhì)量保證的角度出發(fā)怜械,單元測試覆蓋率100%是否就足夠了呢?肯定不夠澳鹿稹宫盔!
結(jié)合實(shí)際的項(xiàng)目經(jīng)驗(yàn)來看,jest的測試還可以根據(jù)產(chǎn)品的實(shí)際需求享完,做一些諸如:
點(diǎn)擊某個(gè)頁面元素后灼芭,需要在頁面上顯示新的區(qū)塊,并且要加載指定的的css的測試;
點(diǎn)擊某個(gè)link般又,需要跳轉(zhuǎn)到指定的網(wǎng)站的測試;
等等
這些測試原本在UI自動化功能測試中也比較常見彼绷,這里我們都可以把它們挪到低層中去。所以具體的測試用例茴迁,在單元測試覆蓋率超級高的前提下寄悯,我們測試的群眾還可以跟研發(fā)結(jié)對完成《橐澹或者指導(dǎo)研發(fā)完成猜旬,要不干脆自己加上去算了。另外倦卖,產(chǎn)品的功能性測試完成的情況下洒擦,我們還需要考慮下非功能性的問題,例如兼容性怕膛、性能熟嫩、安全性等。再加上測試金字塔的頂端之上褐捻,其實(shí)還有探索性測試的位置掸茅。產(chǎn)品的基本功能由單元測試保障了椅邓,剩下的時(shí)間,我們可以做更多的探索性測試了不是嗎?總之昧狮,干掉UI自動化功能測試只是一個(gè)加速測試反饋周期景馁、減少投入成本的嘗試。軟件的質(zhì)量不僅僅是測試攻城獅的事情陵且,而是整個(gè)團(tuán)隊(duì)的責(zé)任裁僧。堅(jiān)持一些重要的編碼實(shí)踐,比如state less的組件慕购、build security in等聊疲,也是提高質(zhì)量的重要手段。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沪悲,一起剝皮案震驚了整個(gè)濱河市获洲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌殿如,老刑警劉巖贡珊,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涉馁,居然都是意外死亡门岔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門烤送,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寒随,“玉大人,你說我怎么就攤上這事帮坚∑尥” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵试和,是天一觀的道長讯泣。 經(jīng)常有香客問我,道長阅悍,這世上最難降的妖魔是什么好渠? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮节视,結(jié)果婚禮上晦墙,老公的妹妹穿的比我還像新娘。我一直安慰自己肴茄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布但指。 她就那樣靜靜地躺著寡痰,像睡著了一般抗楔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拦坠,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天连躏,我揣著相機(jī)與錄音,去河邊找鬼贞滨。 笑死入热,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晓铆。 我是一名探鬼主播勺良,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼骄噪!你這毒婦竟也來了尚困?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤链蕊,失蹤者是張志新(化名)和其女友劉穎事甜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滔韵,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逻谦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陪蜻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邦马。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖囱皿,靈堂內(nèi)的尸體忽然破棺而出勇婴,到底是詐尸還是另有隱情,我是刑警寧澤嘱腥,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布耕渴,位于F島的核電站,受9級特大地震影響齿兔,放射性物質(zhì)發(fā)生泄漏橱脸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一分苇、第九天 我趴在偏房一處隱蔽的房頂上張望添诉。 院中可真熱鬧,春花似錦医寿、人聲如沸栏赴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽须眷。三九已至竖瘾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間花颗,已是汗流浹背捕传。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扩劝,地道東北人庸论。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像棒呛,于是被迫代替她去往敵國和親聂示。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 作為一個(gè)合格的開發(fā)者条霜,不要只滿足于編寫了可以運(yùn)行的代碼催什。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個(gè)周閱讀 8,422評論 1 33
  • react 基本概念解析 react 的組件聲明周期 react 高階組件宰睡,context, redux 等高級...
    南航閱讀 1,052評論 0 1
  • 說在前面 關(guān)于 react 的總結(jié)過去半年就一直碎碎念著要搞起來蒲凶,各(wo)種(tai)原(lan)因(le)。心...
    陳嘻嘻啊閱讀 6,846評論 7 41
  • 在目前的前端社區(qū)拆内,『推崇組合旋圆,不推薦繼承(prefer composition than inheritance)...
    Wenliang閱讀 77,654評論 16 125
  • 函數(shù)式編程,對應(yīng)的是聲明式編程麸恍,聲明式編程的本質(zhì)的lambda驗(yàn)算(是一個(gè)匿名函數(shù)灵巧,即沒有函數(shù)名的函數(shù)。Lambd...
    不安分的三好份子閱讀 1,000評論 0 1