个人总结
很高兴今天收到了开奖电话,拿到本科SP成功结束了秋招!
一轮轮的笔面试是对自己查缺补漏、学习成长的过程。
反思自己对前端的学习过程:2017年10月加入Smartlab411,起步阶段看书比较多但不够透彻,大部分看完代码片就开始撸代码,到了暑假实验室师兄准备秋招毕业,我们也担上了主程的任务,从去年暑假开始更多的是锻炼动手能力,后来前端体系升级导师采用了React作为管理端框架,一点点的踩坑,一步步的摸索。虽说自己的代码理解力提高了不少但对原理的概念稍微有点薄弱,面试提问也被问倒,在此决定分享总结自己的面经。
PS:悲惨的是我八月初硬拉导致右手韧带断裂,目前正在恢复中,这段时间只能靠左手码字。
高频题目(答案后续更新)
1. 原型链
概念:
1).只要创建了一个新函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象;2).所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针;
3).当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。
综上所述,假如我们让原型对象等于另一个类型的实例,则此时的原型对象将包含一个指向另一个原型的实例,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条,这就是原型链。
首先要理解构造函数、原型对象、实例对象,我们以案例讲解:
构造函数:function Fn(){};
原型对象:Fn.prototype;
实例:const fn = new Fn();
上述满足原型三要素以及内部指针指向:
1. 构造函数通过prototype指向原型对象: Fn.prototype => Fn.protype
2. 原型对象通过constructor指向构造函数:Fn.prototype.constructor => Fn(){};
3. 实例通过__proto__指向原型对象:fn.__proto__ => Fn.protype;
4. 实例通过__proto__指向原型对象再通过constructor指向构造函数:fn.__proto__.constructor => Fn(){};
上面关系可以通过画图理解,三者呈三角关系,通过指正关联,
***** 拓展isPrototypeOf() 和 getPrototypeOf() ************
* *
******************* isPrototypeOf() *********************
* *
* 通过Object.isPrototypeOf来判断从属关系 *
* Fn.prototype.isPrototypeOf(fn); *
* Object.prototype.isPrototypeOf(fn); *
* Object.prototype.isPrototypeOf(Fn); *
* *
******************** getPrototypeOf() *******************
* *
* 此时为Fn的原型对象添加一个属性 *
* var proto = Object.getPrototypeOf(fn); *
* proto.name = 'Luvsta'; *
* 打印 Fn.prototype === proto; // true *
* 得到结果:两者相等; *
* proto = {name: "Luvsta", constructor: ƒ} *
* Fn.prototype = {name: "Luvsta", constructor: ƒ}; *
* *
*********************************************************
2. 闭包
概念: 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性:
1.函数内再嵌套函数
2.内部函数可以引用外层的参数和变量
3.参数和变量不会被垃圾回收机制回收
3.HTTP
这里不详细赘述计网的概念,主要分为以下几个方面:
1.谈一谈HTTP/1.0/1.1/2.0以及HTTPS的区别
2.什么是无状态服务,有状态服务呢?
3.状态码 笔者面试问到了206、301、302、304,其他的自行阅读学习
4.有了解HTTPS的SSL吗?对称加密和非对称加密算法
5.TCP、UPD的区别,TCP是如何保证可靠传输的?
6.socket有了解吗?在你的项目中为何要将心跳设置为15s
4.TCP的3次握手、4次挥手
这里需要掌握发送了哪些指令以及Client和Server端的状态
第1题:初始化一个div标签,它的默认宽度(width)是多少?
初始化一个div默认宽度继承父级元素宽度,之所以不显示div是因为高度为0;
如果父元素设置了浮动,子元素也浮动那么这时候div的宽度为0。
第2题:如何用纯div+css实现三栏布局,左右固定宽度,中间自动填充
利用flex弹性盒子布局
父元素display:flex
左右子元素宽度设定固定值宽度(width),中间子元素flex:1
如果想进一步实现多列自动响应式设置flex:1即可
本题尽可能不要采用js动态算变化的宽度,首先考虑用户体验问题。
第3题:JavaScript的函数作用域
1.全局作用域
显示声明:用var声明变量
var name = "luvsta";
var foo = function () {
console.log("this is a function") };
/*---------全局变量会挂载到 window 对象上------------*/
console.log(window.name) // "luvsta"
console.log(window.foo) // ƒ () { console.log("this is a function") }
隐式声明:不用var声明变量
function foo(){
name = "luvsta"; // 直接变量名赋值
return name;
}
foo();
console.log(window.name); // luvsta 此时name为全局变量
2.函数作用域
变量在函数作用域内,外部无法直接访问函数内部变量,但可以通过return访问函数内部变量
function foo(){
var name = "luvsta";
return name;
}
console.log(foo()); // luvsta
值得一提的是立即执行函数是一个单独的作用域
(function(){
var name = "luvsta"
})();
console.log(window.name); // undefined
3.块级作用域(ES6)
块级作用域借助let、const声明变量,在函数执行后变量回收消失,let的优势体现在for循环中的变量
for(let i = 0 ; i < 5 ; i++ ){
setTimeout(function () {
console.log(i); // 0 1 2 3 4
}, 200);
}
for(var i = 0 ; i < 5 ; i++ ){
setTimeout(function () {
console.log(i); // 5 5 5 5 5
}, 200);
}
4.词法作用域
词法作用域是指一个变量的可见性,当我们要声明一个变量时,JS引擎总会从最近的一个域向外层域查找;
var name = 'luvsta';
function foo() {
console.log(name); // "luvsta"
}
function bar() {
var name = 'sam';
foo();
}
bar();
在该案例中,JS查找name这个变量时候发现全局的name更近一些。
5.动态作用域
该作用域查找变量方式与词法作用域相反,与this引用机制有关
动态作用域是基于调用栈的,而不是代码中的作用域嵌套;
掘金文章:谈谈 JavaScript 的作用域 ——作者:leiting1998
第4题:let、var、const的区别
let 的用法类似于