一个普通全日制本科的普通应届毕业生逆向冲分的自述,但愿各路大神勿喷(狗头)。javascript
在去年下半年寒冬将至之时,我还在深圳某间中大型公司的某个温暖的项目组作着前端实习。偶尔在掘金、简书上刷到互联网寒冬的消息也是大体浏览,丝毫没有放在心上。直到有天项目组组长约我谈话,说北京总部那边转正编制今年有改变,除了后端销售那边还有些岗位以外,其余的职位均可能转正不了,特别是前端(我是除了后端实习生以外最后一个离职实习生在2月尾巴)。说实话,当时个人心里除了离开一群可爱的同事感受有点失落其余感受没多大,由于导师的信任把不少需求、bug修复任务分到我身上让我成长了不少。在那4个多月的实习中,我深入理解了Javascript的闭包、原型、继承、预编译过程的函数声明总体提高,变量声明提高、this指向、json数据处理、也独立解决过深拷贝,浅拷贝、防抖节流的问题、ES6经常使用的新语法也常用,对宏观任务和微观任务以及同步异步也有着清晰的理解、能熟练的使用Vue框架和less预编译器独立开发、对组件化和模块化开发也有清晰的理解、熟悉使用git版本管理。因此通俗的说:那时候的我飘了。php
做为一个标准90后,崇尚着“只要心够大,每天是暑假”的理念,刚离职固然先放松放松,因而花一个星期把星耀5的号打上了王者。在那以后,正式开始了个人寒冬之旅,直至今日收到4个offer,虽然没有一个薪资和我预期的同样,但为了生活仍是选择了一个周三入职。在求职这个过程过于曲折,总结了一下:菜是原罪。前端
在这个求职过程当中,我遇到过招前端开发工程师却面试Java、计算机原理、数据结构,理由是面试成功后不必定作前端开发,可能分配后台开发、测试岗位,由于他以为前端技能去培训班培训6个月出来前端技术栈你能够掌握不少,Vue你也能够用得很6,可是计算机原理那些学校教的基础知识才是区分你与培训班出来的不一样。虽然我很认同他说的,奈何嘴上回答不出答案,只能回去等通知了;我也面试过和技术面试官聊了差很少一个多钟的前端技术后(基本能够回答出来)问我php后台开发,由于公司是初创公司,必要时须要进行后台开发,岗位需求有写,最后也只能收获回去等通知;我还面试过须要1-3年工做经验的前端工程师,前端基础都回答上了,却因VueX的问题表述不清晰和未接触webpack提取公共模块问题回答不出,再加上问题的不断挖掘致使自身紧张,最终面试官加了我微信,让我作候选人,这几天没遇到合适就录用我...可是最多见的情形仍是简历投递石沉大海,绝大部分的简历投递只有已到达、已查阅和不适合三个阶段,明明职位要求和本身技术栈匹配却依然回馈不适合的状况司空常见,而更常见的是永远是已到达状态。一次又一次的打击让我都再也不相信本身,指望薪资也心中一次次降低,以致于如今和hr谈薪资都至关佛性,遵从安排,只要仍是正常的薪酬范围点头就完事了。java
预编译—发生在函数执行的前一刻,它在函数执行时总得来讲作了两件事:一函数声明总体提高;二变量 声明提高。那么预编译具体是作了什么事情呢?webpack
从总体页面来看,当script内代码块执行时,预编译作了三件事。git
第一件事情是建立GO(Global Object)对象,也就是咱们熟悉的全局对象es6
第二件事是查找变量声明做为GO属性,值赋予undefinedweb
第三件事是查找函数声明做为GO属性,若是属性名存在,直接把值赋予函数体。面试
当咱们调用一个函数时,在执行前一刻,预编译作了四件事情。ajax
第一件事情是生成一个AO(Actived Object)对象,也就是咱们平时所说的函数做用域对象,保存函数调用时的局部变量。
第二件事情是查找函数形参以及函数内部变量声明,形参名以及变量名做为AO对象的属性,值为undefined。
第三件事情是实参形参相统一,把实参的值赋给形参。
第四件事情是查找函数声明,若是AO对象中属性名与函数名同样,把值赋予函数体。
当代码在执行时,建立出的变量对象的一条做用域链,[[scope]](做用域)存储着一层层的AO与GO的集合,集合呈链式连接就是做用域链,用来指定全部变量和函数的访问顺序,做用域链最顶端始终是当前代码正在执行的变量对象的AO。
闭包—是指有权访问另外一个函数做用域变量的函数。
建立闭包的经常使用方法就是函数里面再建立函数,而后把建立的函数的结果return出去保存到外部。因此当script代码块执行时,先生成GO,而后代码由上到下执行,当执行到外部函数执行前一刻时生成该函数的AO,同时当外部函数执行产生内部函数的定义,因此当内部函数被建立时保存了外部函数的执行环境(AO、GO),并且还未执行就把内部函数被return到外部时,从而致使外部函数释放不了本身的做用域,造成闭包。而当接收了return的内部函数的函数执行时(即 var test = 外部函数();test();),内部函数才生成本身的AO再做用域顶端,同时做用域链上还有外部函数的AO以及GO。
原型链-由原型组成的链叫作原型链。而对象的__proto__就是它的是原型,原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,就这样根据对象的__proto__向上查找,这就是原型链。
原型链继承就是每个构造函数都有一个prototype属性指向该构造函数的父类,当实例对象经过new一个构造函数生成,该实例对象隐性执行了四步。
第一步 var 中间变量 = {}
第二步 将构造函数中的this指向新建立的中间变量。
第三步 中间变量.__proto__ = 构造函数.prototype
第三步 return 实例
因此当一个构造函数的prototype等于另外一个实例对象,而这个实例对象是经过new另外一个构造函数生成的,而另外一个构造函数的prototype.xxx=xxx,经过这种方式第一个构造函数的实例对象就能够访问到另外一个构造函数的父类,这也就实现原型链继承。
下回分解
理论:函数声明空构造函数作中间层(function F(){}),F.prototype属性等于Father.prototype,而后Son.prototype = new F();可是有个继承混乱问题,因此须要把Son的constuctor归位,即Son.prototype.constuctor = Father;(前提声明了Son、Father构造函数)
经典圣杯模式实现继承代码封装:
function inherit(Target,Origin){
function F(){};
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constuctor = Target;
}
复制代码
this指向只有在函数执行的时候才能肯定this到底指向谁。this指向有三种状况
第一种状况:若是一个函数没有被上一级的对象所调用,那么this指向GO,反之即指向上一级对象的AO。
第二种状况:做为构造函数调用,this指向new出的对象的AO。(其中涉及到new操做符调用构造函数时隐式三步骤以及原型链继承概念)
第三种状况:箭头函数没有本身的this,它的this指向上下文的this
说到this指向,又不得不说三个改变this指向的方法—call、apply、bind。它们都是从Function.prototype继承来的(下篇再写具体用法)
数据类型分为基本数据类型(undefined、null、布尔、string、number、symbol(es6新增))和复杂数据类型(object),基本数据类型存储在栈上,存储的是值,而复杂数据类型存储在堆上,存储的是地址。深拷贝和浅拷贝只适用于复杂数据类型,由于当object赋值给另外一个变量其实拷贝的是地址,指向同一块存储空间,当拷贝对象改变原对象跟着改变就是浅拷贝,反之就是深拷贝。简单的数组存储值时可用concat()和slice()实现深拷贝,若是数组存储对象或者数组时可用josn.parse(josn.stringify(obj))。若是是对象经过递归把每一个对象的值赋值给新定义的对象。
javascript拥有一个基于事件循环机制的并发模型。js引擎把任务分红宏观任务(setTimeout、script)和微观任务(promise、process.nextTick) ,先执行宏观任务,再执行微观任务,任务又分同步任务和异步任务,全部同步任务在主线程上执行造成一个“执行栈” ,而异步任务只要有了运行结果就会在任务队列之中放置一个事件,当执行栈里的全部同步任务执行完,系统就会读取 队列任务,查看事件里相对应的异步任务,结束等待状态,进入执行栈开始执行。主线程不断重复这样的操做叫作事件循环机制。
感谢阅读,因为时间关系技术点没有一一根据本身的理解去细说,但愿可以对正面努力迈向前端大门的大家给予帮助。只能说前端技术栈太多了,仍是须要不断的学习,紧跟前端潮流,在前端这条路上也还有很长的路要走。坚持!加油!共勉!