JavaScript核心概念之执行上下文和栈

桃翁桃翁,问个问题呢,据说 js 里面有个执行上下文,这个概念是个什么东东哦?据说挺重要的,给我科普科普呗。 Emm… 这个概念非常的抽象,简单来说呢,就是 JS 在执行某段代码的时候做的一些事情。 具体做的事情就是定义了变量或函数有权访问的其他数据决定了它们各自的行为(作用域链)。每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中(变量包括 this、arguments)。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。 哇,还是好抽象啊,你能不能画个图举个栗子呢? 在之前说的执行上下文就是解释器在执行 JS 某段代码的时候做的一些事,那么首先我们把代码分个类。 Global 代码:代码第一次执行时默认的环境。 Function 代码:执行到一个函数中。 Eval 代码:文本在eval函数内部执行。 看到这个图相信现在分清楚各种类型的代码,每种类型代码会都会产生执行上下文,我们把 Global 代码产生的执行环境叫**「全局执行上下文」,把 Function 代码产生的执行环境叫「执行上下文」**吧,Eval 代码不考虑。 那我看这个图似乎有很多执行上下文(execution context),这个具体是怎么来的呢? 全局执行上下文只有一个,而执行环境的话是每次函数调用都会产生一个执行上下文。注意要调用才会产生哦,不调用是不会产生的。 那这个执行上下文基本知道是个什么东西了,那执行上下文栈又是啥呢? 见名知意,执行上下文栈就是执行上下文(包含全局执行上下文)形成的栈嘛。 那为什么要有这个执行上下文栈呢? 浏览器中 JavaScript 解释器是单线程的,这就是说同一时间代码只会做一件事,那么创建这么多执行上下文,又不能同一时间执行多个上下文,所以就必须要有个顺序,这个顺序就是就是先进后出,这很明显就是一个栈结构嘛。 那我就疑惑了,为啥要先进后出,不先进先出呢? 我们分析一下图一的代码,结合上图,首先我们看图 1,解释代码的时候首先创建的就是全局上下文,然后再创建 person 的执行上下文,然后再创建 firstName 的上下文,然后再执行完毕 firstName ,就把 firstName 的上下文弹出,再 创建 lastName 的上下文,然后执行完毕,再弹出 lastName 的上下文,然后执行完 person 的上下文,再弹出 person 的上下文,再执行全局上下文,然后全局上下文弹出。 如下是一张经典的执行上下文栈的图。 默认进入全局上下文。如果你的全局代码中调用了一个函数,那么程序将会进入这个被调用函数的上下文,创建一个新的执行上下文,并把当前上下文放到栈顶。浏览器总是会把当前执行上下文放到栈的顶部,一旦函数执行完成,这个执行上下文就会从栈中移除,返回到栈中的下一个上下文。 这些大概明白了,不过你说在创建执行上下文做的那些事儿,我还是有点迷糊,能再详细说说吗? 那我们首先看点代码: // 例1 console.log(a); // 报错,a is not defined // 例2 console....

September 25, 2018 · 1 min · 169 words · 桃翁

JavaScript核心概念(1):类型转换

看到这个是不是有一种想打人的感觉,垃圾 JavaScript,这特么都什么鬼,相信很多人不管是笔试还是面试,都被 JS 的类型转换难道过,相信认真看完我这篇文章,妈妈再也不用担心类型转换的问题了。 原始值到原始值的转换 原始值转化为布尔值 所有的假值(undefined、null、0、-0、NaN、””)会被转化为 false,其他都会被转为 true 原始值转化为字符串 都相当于 原始值 + "" 原始值转为数字 布尔转数字:true -> 1, false -> 0 字符串转数字:以数字表示的字符串可以直接会转为字符串,如果字符串头尾有空格会忽略,但是空格在中间,转换结果就是 NaN。 +" 66" // 66 +" 6 7 " // NaN 原始值到对象的转换 null 和 undefined 转对象直接抛异常 原始值通过调用 String()、Number()、Boolean()构造函数,转换为他们各自的包装对象 对象到原始值的转换 对象转为布尔都为 true 对象到字符串 如果对象有 toString() 方法,就调用 toString() 方法。如果该方法返回原始值,就讲这个值转化为字符串。 如果对象没有 toString() 方法或者 该方法返回的不是原始值,就会调用该对象的 valueOf() 方法。如果存在就调用这个方法,如果返回值是原始值,就转化为字符串。 否则就报错 对象到数字 对象转化为数字做了跟对象转化为字符串做了想同的事儿,不同的是后者是先调用 valueOf 方法,如果调用失败或者返回不是原始值,就调用 toString 方法。 补充。一些常用内置对象 toString 方法和 valueOf 的转换规则 toString 相关 valueOf 相关 == 运算符如何进行类型转换 如果一个值是null,另一个值是undefined,则相等 如果一个是字符串,另一个值是数字,则把字符串转换成数字,进行比较 如果任意值是true,则把true转换成1再进行比较;如果任意值是false,则把false转换成0再进行比较 如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的 toString 或者 valueOf 方法。 js 核心内置类,会尝试 valueOf 先于 toString(可以理解为对象优先转换成数字);例外的是 Date,Date 利用的是 toString 转换。非 js 核心的对象,通过自己的实现中定义的方法转换成原始值。 + 运算符如何进行类型转化 如果作为一元运算符就是转化为数字,常常用来将字符串转化为数字 +“2” // 2 2+false // 0 ```...

August 7, 2018 · 1 min · 181 words · 桃翁

拥有自己的知识体系,形成自己解决问题的方法论

前言 最近在星球里群里都有小伙伴说道自己对未来的路比较迷茫,一旦闲下来就不知道自己改干啥,今天我这篇文章就是让你觉得一天给你 25 个小时你都不够用,觉得睡觉都是浪费时间。 今天我谈的就是关于【构建知识体系,形成自己解决问题的方法论】,这个话题以前我在给在校准备找工作的同学的几个建议这篇文章中谈到过,但是没有将如何去构建自己的知识体系,这次将深入这个话题进行探讨。 什么是知识体系 无论是大到一个星系还是小至一个原子,其本质都是一个个的系统。 那我们如何来掌握这个系统呢?通过“框架”来简化对系统构成元素以及元素间有机联系。因此有目的地运用“框架”来思考、学习,能够让我们更全面、更快速、更深入地分析、解决问题,以及更高效地学习新知识和技能。 简单来说,知识体系就是一个系统构成元素以及元素之间的有机联系的简化体现。 知识体系的重要性 没有完整的个人知识体系框架,即使你在学习单个知识点的时候理解力和速度高于一般人,但你整体的学习效率依然会很低。原因如下: 对知识的理解就不深。大部分知识点之间是有联系的,缺少了完整的知识体系框架,你就好似失去了知识间联系的地图,对知识的理解就不深。平时我们在遇到问题的时候不知道怎么解决,然后问了下大佬给你说用啥,然后怎么用之后,你就发现我知道这个知识点,但是没想到可以这么用。 比如以前刚去实习的时候,遇到一个跨域问题,因为后端的数据是早就稳定了的,我只是要去拿几个接口的数据来做点东西,那么我本地调试的时候由于域名是是 locahost,而后端是 xxx.duokan.com, 所以就会有跨域问题,当时我就问我老大我要用代理来解决这个问题吗?他就跟我说你加一条 host ,把 xxx.duokan.com 绑定到 127.0.0.1 就行了,因为我当时知道 host 这个东西,所以就 get 到他的点了,但是由于知识点没有成系统,是散的,就根本想不到 host 和跨域有关系。 **陷入在被动学习当中。**没有完整的个人知识体系框架,你只能是碰到什么问题就被动地去学什么,零散而无系统,从而不自觉地陷入在了被动学习当中。这就跟我在文章的开头提到的小伙伴一样,刚开始还能被动学习,然后就不知道学什么了。 一旦你形成了知识体系,你就知道自己那些地方要补,那些地方暂时可以不补,就可以主动学习去查漏补缺,就不会再迷茫了,因为你会发现你有太多太多遗漏的东西,根本学不完。 **知识整体积累的速度下降。**知识之间是相关联的,不同的人在经历同一段工作或上同一堂课时会因为知识体系框架的不同,从而导致了不同数量级的经验吸收。 知识体系的好处 知识体系 可以方便地 给出所学知识的 地图全貌。在学习过程中给人进度反馈。 梳理知识体系,可以提炼出知识的主干网络,方便知识的调用。 知识体系提供了可拓展性。新学知识可以有规律地添加在原有体系之中。 知识体系为知识的关联提供的指导,发掘知识点之间的关联,正是创新的核心。 把孤立的知识点关联起来,是避免遗忘的重要手段。 其实知识体系和解决问题的方法论是相辅相成的,在自己解决问题的时候,会用到知识体系的东西,知识体系的形成,也有部分是通过解决问题来添砖加瓦的。 怎么构建自己的知识体系 对于构建知识体系和很多方法论差不多,收集、整理、输出(即思考过程)。 **收集知识点。**现在是互联网很发达的时代,收集知识点,已经完全不是一个问题了,可以通过微信公众号、得到、视频网站、博客、社区等各种路径获取知识,你可以讲这些知识点收集起来后面进行整理,但是我提倡是先看再收藏,而不是收藏了等有空再去看,不然就会造成收藏栏里发现自己收藏了一大堆,然而由于太多就不知道看哪个,最后就不看了。 **整理知识。**整理知识是一个为输出做准备的,在整理的过程你已经有一定的思考了,会建立自己的知识分区,将你认为相似的知识点归为一类,慢慢你也会将你的知识库变得更加丰富。 **输出。**输出是来巩固知识的最佳方法,也许你通过自己的大脑想,觉得很简单,感觉自己会了,其实想通过头脑去想,去检验是否已经掌握了,对于绝大部分人来说都是不可能的,因为一般人的大脑都是无法深入到很多层以及思考全面,但是可以通过训练去让自己思考得越来越深入,越来越全面。 这话可能说得有点抽象,咱们举个例子来说,大家都知道围棋很难吧,难的是什么,下完每一步棋之后可能的结果太多了,而那些大师就是可以预测下别人下一步,甚至下好几步别人会下的棋子来推测自己下的这步棋下在哪里比较好,而新手是往往做不到的,而像柯洁这种20就拿世界冠军的,也许就是因为他对围棋的天赋,天生对围棋就有很好的大局观,加上自己努力。 这上面只是谈到了为什么我们不能用大脑来检验自己掌握知识的程度。所以我们可以通过自己的嘴,来给别人讲明白;或者通过写文章站在读者的角度,把自己讲明白。只有能给别人讲明白的东西,才是你真正掌握的东西。 通过画思维导图来把知识体系形象化。 选择思维导图的软件可以从知乎这个问答里面选择自己喜欢的,合适自己软件。有什么免费的思维导图软件可以推荐? - 知乎 这是以前流传的一篇 WEB 前端工程师的一篇思维导图,也可以说是作者的知识体系,我在这里不评价好与不好,因为每个人的技术栈都不同,但是我们还可以针对这个进行细化。 比如我们针对我们前端重要的一块 JavaScript,就可以再进行细分, Javascript 需要掌握基本类型、函数、对象、内置对象、DOM、BOM等知识,然后函数要掌握闭包、作用域、this等,对象要掌握原型、new这些等等。 我就不再扩展了,根据自己的知识形成一个知识体系,然后再解决问题的时候就很容易根据自己的知识体系来解决问题,比如可能你遇到了跨域的问题,你从你的大脑搜索整个知识体系的时候,就可以知道跨域有哪几种方法,然后每种方法的适用场景是什么。 在形成自己的知识体系的过程中,你就知道自己对哪些知识了解,哪些知识不了解,然后你就会花时间去补充自己不了解的知识,渐渐完善自己的知识体系。 在形成自己的知识体系之后,你面试就比较胸有成竹,兵来将挡水来土掩。 你的知识体系就像一张网,面试的过程就是来检验你这张网漏洞有多大的过程,而学习的过程就是就像是给这张网空隙给编织细一点,你的最终目的就是使你这张网的空隙越来越小。 一些小要求 需要有一颗爱学习的心。 需要做一个善于总结的人。 需要是一个有执行力的人,不然列了很多知识点,不去查漏补缺,没鸟用。 关注桃翁,关注前端桃园,有问题随时跟我交流。(最后一条纯属扯淡)

August 3, 2018 · 1 min · 68 words · 桃翁

毕业记—我的大学无憾了

如果玩抖音的同学,我相信对上面这个图片并不陌生,在六月份的时候疯狂刷这个,但是当时并没有任何感觉,直到我那毕业的那天,提起背包离开学校的那天,我才真正的感受到,我要离开学校了。 自己已经不是一个学生了,熟悉的学校,熟悉的班级,熟悉的同学,熟悉的老师,这次,真的说再见了。 还没来得及跟给我传授过知识老师,陪了我四年的大学同学,以及实验室的学弟学妹们好好的说再见,就提着行李,背着书包离开了学校。 在走的那天,突然想到,那些给我传道受业解惑的老师,那些跟我一起学习上课的同学,那些跟我在实验室辛苦奋斗的都学弟学妹们,也许我们以后就见不到了,莫名的一股泪意席卷而来,包括我现在写这篇文章也是这样,这也行就是人与动物之间感情的差别吧。 天下无不散之筵席,想给那些没有好好道别的人说,咱们有缘再见,以后我帮得上忙的随便找我。 之所以在题目取【我的大学无憾了】,主要是因为三件事儿。 **找到了一份满意的工作。**虽然我没能去得了我最想去的腾讯,也因为个人原因没有去实习了半年的小米,但是在现在的蘑菇街工作我还是挺开心,很满意这里的工作氛围以及人文环境。 在大学中找到了心爱的女朋友。 都说程序员比较宅,很难找到女朋友,还好我运气好,在毕业之前找到了心爱的她。 拿到驾照。 大学有时间真的建议把驾照考了,以后工作了时间成本很高。 夸夸自己 我在学习上说是一个学霸呢,但是自我感觉并没有怎么花时间去学习上课的内容,大多数时间都花在专业课上,准确的说是花在敲代码上。 为啥又说是个学霸呢?因为拿的奖状还是挺多的,四年里,拿了两次甲等、一次乙等(跟甲等的最后一个绩点只差 0.1),大四由于没课,只有一个实习,不知道老师咋打的分,后来没有拿到。 然后在其他方面参加的比赛比较多,各种程序设计大赛,数据库设计大赛,以及优秀班干部等等,估计 20 多张奖状,最后毕业前还去申请了校级的优秀毕业生和市级的优秀毕业生,没想到都通过了,市级优秀毕业生咱们一个院也才 5 个名额,这个时候只想对自己说【优秀】。 吐槽下自己 在这里想吐槽自己的主要是体重,总结下来就是【肥了】。 刚入大学的时候我只有 114 斤,作为一个 174 的男生来说,那还是比较瘦的了,想想那个时候自己肚子稍微硬一下,还能看到几块肌肉呢,大一的时候比较闲,没事儿就出去大大篮球,然后对新事物比较好奇,到处跑啥的,运动的比较多。 到了大二的时候,涨到了 122 左右,因为大二进了学院的创新实验室,从此没有了双休,没有正常的节假日,没有了没有课就是玩的时间。如果早上没有课 8 点 40 之前就得到实验室,晚上一直要干到 10 点 40 才能回寝室,每周要上六天班。每天三点一线,寝室、教室、实验室,周末休息的那天就想着要好好打打游戏,放松下,也没有出去玩,导致体重增加,肚子肥肉增多。 到了大三同样也如此,绝大部分除了睡觉的时间都是在实验室,很少出去运动,只要在体育课的时候才能好好的运动,直到大三结束的那个暑假,已经 126 了,但是还是没有意识到问题的严重性,感觉还是很正常,也不胖。 大三结束的那个暑假,我去小米实习了,虽然在北京消费很高,但是总是吃得很饱,几个玩得好的每周都要出去吃好的,结果越吃越胖,直到有一次去吃完火锅回来在旁边的称称了一下,把自己下了一跳,已经 135 了,那个时候才来北京两个月,竟然涨了 9 斤,准备开始减肥了,然而并没有坚持下来,但是尽量在注意,直到我实习半年再回学校 138 了。 回到学校已经是大四了嘛,就在学校做毕业设计,在学校吃的稍微差点,我也尽量控制自己的食量,现在以及只有 132 了。 结语 希望自己离开了社会,该变的要变,不该变的别变。比如不要忘记初心而随波逐流,既然选择了做程序员这个行业,目前这几年就应该有工匠精神,把技术专研深,专研透,以后看自己的意愿或者社会的发展再看应该干什么。 要该变的是该变自己还是学生的身份,作为一个工作人,应该对工作精益求精,尽量不要犯错误,大学的时候犯点错误还能接受,在公司里犯了错可是要付很大的代价的。 最后感谢大学陪我走过的这些人,可能有些人只是我人生中的过客,但是也给我的人生增添了一份色彩,感谢你们。 那些在大学里面给过我帮助的人,我会永远记住的,【滴水之恩,涌泉相报】。 我希望今天我以学校为荣,以后学校以我为荣。 致我的大学以及青春。

July 7, 2018 · 1 min · 58 words · 桃翁

Javascript 是最好的语言,不服来辩

看到这个标题相信很多人就要开始跟我争论了,PHP 才是最好的语言,那就请原谅下,你说是就是,我们来看看就知道了。 有一条 Atwood 定律:any application that can be written in JavaScript, will eventually be written in JavaScript 翻译一下就是:任何可以用 JavaScript 来写的应用,最终都将用 JavaScript 来写 要是没看到过这句话的人可能又要开始说了,Atwood 是谁,他说最终会就会啊。 那我们来了解一下他,说那些多少年的编程经验啊,这些都没啥用,只要说一点,就能知道这个人也不是等闲之辈,他是 stack overflow 的联合创始人,还是牛逼吧,如果你说你不知道 stackoverflow,那么对不起,那么我们不能做朋友了(开玩笑的,不知道的去了解下吧) Javascript 可以做什么 1. Web 前端 相信这个这个是毫无疑问的,在 Web 前端的地位目前是没有任何语言能撼动它的霸主地位。 2. 后端 Nodejs Node.js 是一个 Javascript 运行环境(runtime environment),发布于2009年5月,由Ryan Dahl 开发,实质是对 Chrome V8 引擎进行了封装。Node.js 对一些特殊用例进行优化,提供替代的 API,使得V8在非浏览器环境下运行得更好。 使 Javascript 走向了服务端,这使得 Web 应用仅用一种语言即可完成。 3. 桌面应用 代表 Electron ,还有 Node-webkit 、heX Electron 是由 Github 开发,用 HTML,CSS 和 JavaScript 来构建跨平台桌面应用程序的一个开源库。 Electron 通过将 Chromium 和 Node....

May 24, 2018 · 2 min · 336 words · 桃翁