https://zhuanlan.zhihu.com/p/...
對於必需要在DOM加載以前運行的JavaScript腳本,咱們須要把這些腳本放置在頁面的head中,而不是經過外部引用的方式,由於外部的引用方式增長了網絡的請求次數;javascript
async
表示異步加載JavaScript文件,它的下載過程能夠在HTML的解析過程當中運行,加載完成以後當即執行這個文件的代碼,執行文件代碼的過程當中會阻塞HTML的解析,它不保證文件加載的順序。defer
表示在HTML文檔解析以後再執行加載完成JavaScript文件,JavaScript文件的下載過程能夠在HTML的解析過程當中進行,它是按照script標籤的前後順序來加載文件的。css
map
返回一個新數組forEach
遍歷數組,返回值爲undefinedreduce
累加器,遍歷時避開建立新數組減小冗(rong)餘,返回值由參數callback決定html
session
會在必定時間內保存在服務器上。當訪問增多時,會佔用服務器的資源,因此考慮服務器性能方面,可使用cookiecookie
存儲容量有限制,單個cookie保存數據不能超過4k,且不少瀏覽器限制一個站點最多保存20個cookie。對於seesion,其默認大小通常是1024klocalStorage
本地存儲和cookie都保存在瀏覽器端,且都是同源的。每一個域5MB前端
apply
接受2個參數:一個是在其中運行的函數做用域(Scope),另外一個能夠是arguments
也能夠是Array
的實例,經典案例:#獲取數組中最大的值#;#使用push合併數組#;call
和apply
用法相同,只是除了第一個都是做用域以外,其他參數必須逐個列舉出來。經典用例:#使用call調用匿名函數#bind
接受1個參數,返回一個新函數,這個新函數的this值來自bind(context)函數傳遞的contextvue
Function.prototype.bind = function(context){ var self = this; //原函數 return function(){ //返回一個新函數 return self.apply(context, arguments) } }
https://segmentfault.com/a/11...
思路一:
1.雙層循環,外層循環元素,內存循環時比較值
2.若是有相同的值則跳過(break),不相同則push近數組
思路二:利用splice直接在原數組進行操做(刪除元素時,須要更新數組長度)
思路三:利用對象的屬性不能相同的特色進行去重
思路四:數組遞歸去重
1.運用遞歸的思想
2.先排序,而後從最後開始比較,遇到相同,則刪除
思路五:利用indexOf以及forEach
思路六:利用indexOf以及sort
思路七:利用ES6的setjava
當在函數內搜索一個變量時,若是函數內沒有這個變量,那麼這次搜索過程會隨着代碼執行環境建立的做用域鏈往外逐層搜索react
全局變量的生存週期是永久的
對於函數內var聲明的局部變量,當退出函數時,這些局部變量會隨着函數調用結束而被摧毀git
局部變量所在的執行環境還能被外界訪問,那麼這個局部變量就有了不被摧毀的理由github
使用閉包的動機:主動將一些變量封裝在閉包中,以便將來還須要使用到它們。
把變量放在閉包中和放在全局做用域,對內存的影響是一致的,這裏並不能說成是內存泄露。若是未來須要回收這些變量,咱們能夠手動把這些變量設爲null面試
包裝函數嵌套太深,且被不推薦使用mixins模式
組件太大,學習成本過高,高度集中化沒法將細化功能抽離出來
有時候不知道使用classes仍是function建立函數
有時在lifecycle內註冊完事件後,又須要在摧毀階段手動註銷事件
註冊監聽事件後,又須要在組件變化時手動發佈事件
let string = ''; Boolean(string) //false function return ( <View> {string&&<Text>前面的不會進行bool類型轉換</Text>} </View> //會報錯 )
具體參考: https://www.robinwieruch.de/r...
Redux受函數式編程影響,它老是返回一個新狀態,而不是改變狀態。
//不要在Redux這樣作,由於這樣會改變數組 function addAuthor(state, action) { return state.authors.push(action.author) } //保持不變,老是返回一個新對象 function addAuthor(state, action) { return [...state.authors, action.author] }
state數據遵守標準化數據格式,能夠保持state數據扁平化(flat state)和單一(身份)信息源(single source of truth) 。
{ post: { id: 'a', authorId: 'b', ... }, author: { id: 'b', postIds: ['a', ...], ... } }
Mobx既有面向對象編程,也有反應式編程。它將你的state包裹在可觀察(Observable)的狀態中。所以,你能夠在state中得到全部可觀察的功能。
在Mobx裏state是可變。所以能夠直接改變state:
function addAuthor(author){ this.authors.push(author) }
數據結構state能夠保持深層嵌套
在Redux中, 狀態是隻讀的,只能使用 顯示操做actions來更改狀態。相反,在Mobx中,狀態容許讀寫,能夠直接改變狀態without actions
https://stackoverflow.com/que...
例如:
//state內的list引用redux中的list this.state={ list:this.props.list||[] } //component內修改list值 this.setState({list:[1,2,3]}) //此時redux中的list也被改變,只是沒有將變化傳遞到action console.log(this.props.list) //[1,2,3]
redux的核心概念之一是 #state是不可變的#;使用Object.assign()
合併對象沒法實現深拷貝
https://stackoverflow.com/que...
沒法知道數據是在何時改變(或update)的,而且很難跟蹤(參照redux-logger和mobx-logger)
why is setState asynchronous?
回答這個問題首先要闡述:調用setState時會發生什麼?
調用setState
時,React會將setState()
的對象以「和解」(reconciliation)的過程合併到組件的當前狀態()並以此建立一個新的React元素樹(我理解爲虛擬DOM樹
)。
將新的DOM樹和setState以前的虛擬DOM樹進行相比較(diff
),根據結果對UI進行精準響應。
所以我的理解爲:對比過程須要消耗必定時間,爲了防止阻塞因此將setState
設置爲異步
另外一篇文章:從 setState promise 化的探討 體會 React 團隊設計思想
https://github.com/livoras/bl...
算法實現
步驟一:用JS對象模擬DOM樹
步驟二:比較兩棵虛擬DOM樹的差別
這兩個樹的徹底diff算法是一個時間複雜度O(n^3)
的問題,可是在前端當中,不多會跨越層級地移動DOM元素。因此Virtual DOM只會對同一個層級的元素進行對比:
1.深度優先遍歷,記錄差別
2.可能會有的差別類型
2.1 替換掉原來的節點
2.2 移動、刪除、新增子節點
2.3 修改節點的屬性
2.4 文本節點被改變
var REPLACE = 0 var REORDER = 1 var PROPS = 2 var TEXT = 3
3.列表對比算法
關鍵算法:#字符串的最小編輯距離#(Edition Distance); #Levenshtein Distance#; O(M * N)
步驟三:把差別應用到真正的DOM樹上
?
???
https://reactjs.org/versions/
收到這個問題前我還歷來沒關心過每次發佈新版本更新了哪些,這個問題讓我成長不少。
function scaleSize(size) { let screenW = Dimensions.get('window').width>Dimensions.get('window').height?Dimensions.get('window').height:Dimensions.get('window').width; const defaultWidth =375; // 在UI圖上的基礎寬度 const _scaleWidth = screenW / defaultWidth; return size * _scaleWidth; }
https://www.jianshu.com/p/e42...
基本原理:
1.利用Object.defineProperty
監聽對象賦值動做
2.遍歷全部節點
3.使用觀察者模式對擁有v-model
屬性的DOM節點訂閱上述時間
4.對擁有v-bind
屬性的DOM節點進行發佈事件
5.對錶單標籤使用`addEventListener('input',function(e){/.../})監聽事件
Object.defineProperty(vModelList, key, { enumerable: true, configurable: true, set: function (newVal) { // 發佈 _observer.trigger(key, newVal) } });
https://segmentfault.com/a/11...
String.prototype.render = function(context){ return this.replace(/\{\{([^\}]+)\}\}/g, (match, key) => (context[key]||match)); } "你好,{{name}},咱們會在{{day}}天以內通知面試結果。".render({name:"Niko",day:3})
https://www.zhihu.com/questio...
很簡單,就是利用<script>標籤沒有跨域限制的「漏洞」(歷史遺蹟啊)來達到與第三方通信的目的。當須要通信時,本站腳本建立一個<script>元素,地址指向第三方的API網址,形如: <script src="http://www.example.net/api?pa...;param2=2"></script> 並提供一個回調函數來接收數據(函數名可約定,或經過地址參數傳遞)。 第三方產生的響應爲json數據的包裝(故稱之爲jsonp,即json padding),形如: callback({"name":"hax","gender":"Male"}) 這樣瀏覽器會調用callback函數,並傳遞解析後json對象做爲參數。本站腳本可在callback函數裏處理所傳入的數據。 補充:「歷史遺蹟」的意思就是,若是在今天從新設計的話,也許就不會容許這樣簡單的跨域了嘿,好比可能像XHR同樣按照CORS規範要求服務器發送特定的http頭。
https://segmentfault.com/a/11...
1.DNS解析
2.TCP鏈接
3.發生HTTP請求
4.服務器處理請求並返回HTTP報文
5.瀏覽器解析渲染頁面
6.鏈接結束
禁止使用flex
請使用flex完成