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完成