blog
blog copied to clipboard
用于在Issues中存放自己写的技术文章和分享用
作者:殷荣桧@腾讯 目录: 一、变量相关 二、函数相关 三、尽量使用ES6,有可以能的话ES7中新语法 现在写代码比以前好多了,代码的格式都有eslint,prettier,babel(写新版语法)这些来保证,然而,技术手段再高端都不能解决代码可读性(代码能否被未来的自己和同事看懂)的问题,因为这个问题只有人自己才能解决。我们写代码要写到下图中左边这样基本上就功德圆满了。 >注:由于个人水平与眼界的原因,这篇文章中并没有完全覆盖到常见的写代码的不好的习惯,所以你如果觉的有需要补充的,都可以在文章下方评论,或者直接到我的Github的这篇文章中评论。对于有用的,都将补充到我的掘金和Github中去。同时,你如果觉的文章写得还可以,Please在我的Github中送上你宝贵的Star,你的Star是我继续写文章最大的动力。 一、变量相关 (1)变量数量的定义 NO:滥用变量: let kpi = 4; // 定义好了之后再也没用过 function example() { var a = 1; var b = 2; var c =...
### 目录: 一、代码如何被解析成DOM对象 二、节点的方法是如何添加到DOM上的 三、简单模仿浏览器挂载DOM方法 四、看JSDom源码的疑问 五、了解元素的实例化 一、代码如何被解析成DOM对象 就以如下的一行代码为例,开始探索代码解析的历程,先提出第一个疑问,这三行代码,是怎样解析成DOM对象的? ``` // 代码如下 hello world ``` DOM对象如下:  截图中生成AST的[链接](https://astexplorer.net/#/gist/c11b7d0caa74cf8a42e60c01e47677cc/89bf91cd0ba67a0ccd48c578eda6800c41e6a166),你可以去点击尝试修改HTML代码生成抽象语法树试试。这是浏览器拿到我们所写的HTML文本代码第一步所要完成的事,因为文本的格式是不便于操作的,比如现在要去一个div节点的属性id的内容(exampleId),你说怎么取,估计你能想到用正则表达式,但是不能就靠正则表达式过日子啊,要取的属性各种各样,还有自定义的属性要取,这时候正则表达式表示也顶不住了。只有把文本的内容生成一定的数据结构才方便对其进行操作(如这边生成的AST抽象语法树)。这样通过类似document.html.body.div.attrs.id就可以成功取到。 如果你对浏览器将HTML生成抽象语法树的细节感兴趣,看chrome源代码几乎是不太可行的,你可以查看这样一个GitHub仓库:[parse5](https://github.com/inikulin/parse5),这个是用JS实现的,方便查看,你甚至还可以查看一个正则表达式版本的,也就是我前面提到的啥都用正则表达式来处理的,GitHub仓库:[html-parse-stringify](https://github.com/HenrikJoreteg/html-parse-stringify) 二、节点的方法是如何添加到DOM上的 解决了第一个问题,产生了一个简单的抽象语法树,接下来问题又来了,平时我们用的document.getElementByTagName在我们这个抽象语法树上并没有,我们只有简单的HTML结点的属性nodeName,tagName之类的,并没有这些方法,那么这些获取节点的方法又是从哪来的呢? 注:在chrome的控制台中直接输入document或使用console.log(document)是没法查看document属性的, 需要使用console.dir(document)来查看其属性。查看的属性如下图所示:  打印出浏览器的docuemnt对象后,我们在原型链上向下翻了好几层,终于找到了我们想要找的getElementByTagName,是挂载在Document这样的一个原型链处,如下图所示。为什么又来一个Document,和我们之前的console.dir(document)中的document有什么不同?   到了这边就需要搬出我们的W3C标准来了,为什么打印出来的document对象上有那么多的属性,有那么长的原型链?因为这些都是W3C标准规定的,就以一个上图中的属性字段URL为例,都是W3C规定的Docuemnt上需要有哪些属性,可以点击这里查看所定义的属性,[查看这里](https://dom.spec.whatwg.org/#interface-document)。可以看出document是一个类似与Document的实例,实际上他们中间只是又隔了一层HTMLDocument。 那么原型链又是如何定义的呢,在W3C标准中可以看到是通过接口继承来实现的,你可以在标准中查到如下字样: interface...
**作者:殷荣桧@腾讯** 这篇文章可在我的 github 中查看,如果你觉得写的还可以,Please送上你宝贵的star. 写在最前面:你一定要坚持看完这个故事,看完你一定会懂Rxjs.千万不要觉得故事情节没有《盗墓笔记》好看而放弃。因为臣妾实在是只能把枯燥的程序写成这个很(挺)有(简)趣(陋)的故事了。 Rxjs的故事有以上图中几个主角,我们来一一介绍,这几个主角你一定要认识。 (1)Rx.Observable 是一条河流。 (2)source 作为一条在河流中捕鱼船上的竹筒。鱼(data)可以一个一个的钻到竹筒中(source)‘ var source = Rx.Observable.create(subscriber) (3) subscriber 是位捕鱼的渔人,是位好心人,主要任务是把捕获的鱼(data)扔向岸边的饥民 var subscriber = function(observer) { var fishes = fetch('http://www.oa.com/api'); // 捕获到鱼 observer.next(fishes.fish1); //...
作者: 殷荣桧@腾讯 本文[地址](https://github.com/jackiewillen/blog/issues/18),欢迎查看 本文[github仓库代码地址](https://github.com/jackiewillen/build-your-own-vuex),欢迎star,谢谢。 如果你对自己用少量代码实现各个框架感兴趣,那下面这些你都可以一看: [build-your-own-react](https://github.com/jackiewillen/build-your-own-react) [build-your-own-flux](https://github.com/jackiewillen/build-your-own-flux) [build-your-own-redux](https://github.com/jackiewillen/build-your-own-redux) 目录: > 一.完成最简单的通过vuex定义全局变量,在任何一个页面可以通过this.$store.state.count可以直接使用 > > 二.vuex中的getter方法的实现 > > 三.mutation和commit方法的实现 > > 四.actions和dispatch方法的实现 > > 五.module方法的实现 > > 六.实现:Vue.use(Vuex) 先来看一下用自己实现的的vuex替代真实的vuex的效果,看看能否正常运行,有没有报错: 从运行结果来看,运行正常,没有问题。接下来看看一步一步实现的过程: 一. 完成最简单的通过vuex定义全局变量,在任何一个页面可以通过this.$store.state.count可以直接使用...
用少量的代码实现redux核心部分及其演化历史 殷荣桧@腾讯 [本文源代码地址](https://github.com/jackiewillen/build-your-own-vuex) [本文Github地址,欢迎star](https://github.com/jackiewillen/blog/issues/17) 先来看一下,完成文章标题所说的,需要完成哪些任务: TODO LIST(计划列表) 1.redux中reducer的实现 2.redux中action的实现 3.redux中store的实现 3.5 先不使用redux,直接用react实现一个主题定制页面的开发 3.5.1 使用props传参完成父子组件共享同一个全局变量(演示全局变量的原始层层传递共享数据) 3.5.2 使用react提供的Context上下文完成父子组件全局变量的共享(演示全局变量使用react context 跨越组件共享数据) 4.结合自己实现的redux实现一个主题定制页面的开发 5.redux中的connect的实现。(结合react中的context实现) 6.结合connect react把主题定制页面再实现一遍 7.redux中添加mapStateToProps 8.redux中添加mapDispatchToProps 9.结合mapStateToProps,mapDispatchToProps 主题定制页面 10.redux中的provider的实现 11.使用provider重构代码 12.使用真正的react-redux替代进来,看项目是否正常运行。代码整理,provider中页面刷新相关的移动到connect,语法检查,错误检查,添加注释,合并commit 接下来我们试着一个一个去实现。当然这其中包括了为什么需要redux的历史演化的过程,总的用了十几个commit来完成了这篇文章,基本上每个commit实现TODO...
作者:殷荣桧@腾讯 目录: 1. 为什么需要Flux设计模式 2. Flux设计模式是怎么实现的 本文对应Github地址,如果觉得文章还可以,希望您送上宝贵的Star 先来看一下最终结果,免得你觉得太复杂,跑了。怎么样是不是简单,那就继续往下看吧。 老外搞个新东西就喜欢给其取个Cool的名字,什么Flux,Redux,Meteor。本来英语就不是太好的中国人一看就跑路了,What?老子Javascirpt还没学好,你又来这这些。名字都看不懂,还学啥。纷纷感慨:老子学不动了,不要再更新了。其实吧,老外就是把公司的个人档案管理流程应用到了前端数据管理流程中了,然后取了吓跑了很多人的名字Flux而已,不信我给你实现一个[简单版的Flux架构](https://github.com/jackiewillen/fluxExample)(代码中对照个人档案管理流程讲解Flux流程),结合下面这张图你再看看是不是。  1.为什么需要Flux设计模式 (1)刀耕火种的年代 最初因为前端就是几个页面和几个js文件,前端对于网站中的全局变量(全局变量就是在哪个页面都可以被访问和修改的变量,如网站的标题)基本上用 window.title = 'XXX' 就可以了。刚上手项目,你全局搜一下window这个关键字也差不多对项目中的全局变量都有个印象了。然后有一天,线上网站中标题出错了(比如:‘爱牛网’ 变成了 ‘屠牛网’),老板一看吓的不轻,让你赶紧看看。你就全局搜一下window.title看一下,原来在D页面title被一个新来的员工改错了(新员工在测试环境下改代码改着玩的,忘删了)。然后你把它修改过来就可以了。 (2)MVC时代 前端发展到中期,应用的场景开始增多,需要一个框架来降低代码的耦合了,Backbone类似的MVC框架出现。通过各个Model来存放数据,包括全局的数据。这个时候全局变量可以通过View(页面)来修改Model中的数据,再反馈到其他的View中去,做到数据同步。这个时期基本上是做一个博客网站,管理系统的体量。 (3) 前端大爆炸时代 前端发展到现在,所应用的场景就越来越多了。有个同学小扎(马克·扎克伯格)在大学里想做个叫Facebook的社交应用,就让前端的朋友帮忙做一做页面。前端同学很快用MVC模式搞定了Facebook前端架构。但是令小扎同学没想到的是,这个叫Facebook的应用火了,功能不停的迭代,增加。前端到同学表示每天加班加点累到只能看着自己手中小扎刚发的1000万美刀的股票骂骂娘。这个时候的前端体量急剧膨胀,上百个View(页面)出现,对应上百个Model(存放前端数据的专用层),经常会出现多个页面对同一个Model数据进行操作,比如有个全局数据刚添加到Model,又来一个页面通知这个全局变量要删除,这个时候其他页面还不知道这个全局变量已经删除了,表示要修改这个数据,再来个页面又要获取这个数据,这个时候就导致前端的数据管理异常的混乱,任何一个页面都有权操作全局变量。你能想象一个公司的员工档案信息中心(类似全局变量)如何任何员工(页面)都可以过来随意的增删改查,你信不信没过几天,你再去档案库查看你的档案,你的学历会变成幼儿园。这个档案信息中心的数据将会一塌糊涂。这就是Facebook有一断时间总是会出现你有未读消息提示,但是你点进去查看却没有任何消息的问题。小扎同学因为这个问题被无数的美国网友骂 What the hell.小扎那叫个火大啊,把前端的主管叫过来一顿痛骂(把美国网友送给他的What the hell都送给了这位主管),让其一个星期内解决此问题(以上骂娘故事纯属虚构,)。这个时候Flux就出现了。这就是为什么需要Flux设计模式。 2.Flux设计模式是怎么实现的 ...
_proto_和prototype的区别 作者:殷荣桧@腾讯 为什么会遇到这个问题呢,是因为我在用构造函数时发现用console.dir(constructor)其中有一个属性叫prototype,还有一个属性是__proto__,不仅是构造函数,普通函数也有(这个其实好理解,因为构造函数其实就是命名的时候函数名用了大写,本质上也是普通函数)。但是当查看对象的时候,发现其中只有一个\_\_proto\_\_的属性。如下图:  那么问题就来了,这两者有什么区别呢,都是干什么用的呢。 先初步了解一下prototype和\_\_proto\_\_的区别. 1. 只有函数才有prototype属性。 2. \_\_proto\_\_是由prototype产生的。prototype是\_\_proto\_\_的父亲。 先来看一张图,再去深入的了解两者的差别:  从图中可以看出,所有的\_\_proto\_\_都是指向一个prototype.来看一个实例就知道原因了。 先写一个构造函数Foo,如上图所示的Foo: function Foo(name){ this.name=name; } 用这个构造函数来构造一些foo对象, var foo=new Foo('foo'); 这时Foo.prototype===foo.\_\_proto\_\_ //return true;正如图上所示。那么这个new了一下到底发生什么了呢,怎么就让foo.\_\_proto\_\_指向了了Foo.prototype呢。接下来就剖析一下new的过程中发生什么了。 function New(func){ var res={}; if(func.prototype!=null){...
文章发表于知乎:深度剖析Margin塌陷,BFC,Containing Block之间的关系
Array对象与Object对象的区别 作者:殷荣桧@腾讯 先来看两张图: 先看一个数组的数组打印出来是什么样的:  接下来将对象打印出来:  其实你会发现,两者只有一个差别:就是一个有length属性,一个没有 1.先来讨论除了length之外的一些差别: 其实数组也可以这样定义: var myArray = Array(); myArray['A'] = "Athens"; myArray['B'] = "Berlin"; 接下来再看一下object的定义 var myObject = {'A': 'Athens', 'B':'Berlin'}; 那定义完数据后访问也没有差别: 数组和对象都可以通过myArray.A来访问。但并不是每种情况都是这样,比如: 前面的var...