参考面经(字节): https://segmentfault.com/a/11...
推荐几个学习的网站:
现代JS教程::https://zh.javascript.info/
JS词典:https://developer.mozilla.org...
阮一峰老师的ES6入门:https://es6.ruanyifeng.com/#d...
问题区
1.JS
- ES6基本类型 ?
- Set,Map区别? Set无序,类似于数组。可以用于数组快速去重。Map类似于json数据,键值对,但是键可以是对象。
- 判断数组的几种方法?为什么要用Object.prototype.toString(),数组的.toString()不行吗,输出什么
- 讲一下事件流,怎么阻止冒泡?如何移除事件绑定?
- ES6 ,ES7新特性?
2.HTMl和CSS
- flex常见属性,如何实现类似快手这种视频列表的瀑布流布局(一行两个) flex:1的含义
- css动画的实现方式?具体一些
- position每种属性的作用
3.编程题
- 什么是面向对象?面向对象特性?与面向过程的区别?
把大象放进冰箱 分别用面向对象,面向过程,函数式编程实现。 - 求二叉树每层的最大节点,放入数组输出。(需要自己构造一棵二叉树去验证) 问优化:怎么只用一层循环实现层序遍历
- 实现复杂版本的bind,可new可继承
- 实现一个函数,将输入的数组转为链表,并实现一个方法向链表指定位置插入值
- 两个无序数组合并成一个有序数组,问时间复杂度。 延伸:快排和冒泡排序的时间复杂度,使用场景
- 实现toFix函数
- 说一下instanceof的原理,实现一下
- 知道map方法吗?实现一下。 reduce和基本版都写了
- 实现ajax,至少实现get和post方法。这里深挖了get和post具体的传参方式以及ajax中具体是如何实现的
- 实现一个模态框组件,用vue和react均可(要能传递确定取消事件函数,有遮罩,居中)
- 看代码输出(考察this和const,let区别)
4. 项目
- 实习项目,主要关心做的项目的作用和难点
- 自己写的最好的组件
- react和vue的区别,各自的生命周期
- vue 路由,hash和history的区别,你们项目中是怎么进行状态管理的,怎么配置路由的?
- 常见的HTTP请求以及每个请求的作用?GET和POST的区别
- 前端安全措施,常见的安全问题,XSS?CSRF
- https ca证书的作用,SSL层的作用
- 路由切换页面的原理?
- 如何尽可能发现代码中的bug,有没有一些工具去辅助
5. 计算机相关知识
- 你知道的数据结构有哪些?数组是数据结构吗?不是,那为什么?什么是数据结构?你刚刚说到了堆,堆是一种新的数据结构吗?不是,是完全二叉树。什么是完全二叉树?
- 树和图的区别? 图的应用场景?
- 网络模型以及每层的协议?
6. 其他
- 别人的评价
- 自身的优点和缺点
- 压力最大的时候?怎么排解压力
- 你对于以后前端学习的规划?
答案区
1.1 ES6基本类型
String,Bool,Undefined,Object,Symbol,Number,Null
1.2 Set对象详解
参见https://cloud.tencent.com/dev...
- Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
- Set特殊值:Undefined和Infinity只能存一个;NaN只能存一个,虽然不相等;
- Set可与Array互换 :
let arr = new Array([...Set对象])
let set=new Set(arr)
- Set作用:并交差集,数组去重。
let a=new Set([1,2,3]);
let b=new Set([2,3,4]); //并集
let union=new Set([...a,...b]);
console.log(union); //交集
let intersect=new Set([...a].filter(x=>b.has(x)));
console.log(intersect); //差集
let diff=new Set([...a].filter(x=>!b.has(x)));
// 数组快速去重
console.log([...new Set(arr)])
1.3 判断数组的几种方法
参见https://juejin.cn/post/684490...
下面几种方法前两个不准确
- arr instanceof Array 缺点:不同执行环境下,判断不正确问题
- arr.constructor ===Arrray 缺点:constructor可被重写;不同执行环境下,constructor判断不正确问题
- Array.isArray(arr)
- Object.prototype.toString
如:Object.prototype.toString.call(arg)==='[object Array]'
instanceof 判断实例是否属于某种类型,逻辑上是按照该实例的__proto__一层层向上找,子类或者后代同样适用。
它假定只有一个全局环境。如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。
toString 可以用toString封装一个函数,判断变量的类型
function getType(obj) {
return Object.prototype.toString.call(obj).slice(8,-1);
}
var a = [1,2,3];
console.log(getType(a)); //Array
var b = function(){};
console.log(getType(b)); //Function
**typeof(Arr) ** // Object 不可用于判断Array,一般用来判断基本类型
typeof基本用法参见下图
1.4 事件流,阻止冒泡,接触事件绑定
https://segmentfault.com/a/11...
1.事件流
描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。
2.事件
就是用户或浏览器自身执行的某种动作。诸如click(点击)、load(加载)、mouseover(鼠标悬停)。
3.事件处理程序
响应某个事件的函数就叫事件处理程序(或事件侦听器)。
addEventListener()
和removeEventListener()
。所有DOM节点中都包含这两个方法,并且它们都接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。当这个布尔值为true
时,表示在捕获阶段调用事件处理程序;若果是false
,表示在冒泡阶段调用事件处理程序。
调用顺序:捕获阶段
,按照由外之内调用事件处理函数;冒泡阶段
,按照由内至内调用事件处理函数;捕获阶段
又在冒泡阶段
调用事件处理程序时:事件按DOM事件流的顺序执行事件处理程序,且当事件处于目标阶段时,事件调用顺序决定于绑定事件的书写顺序(ps:目标阶段是指点中的最内节点)
阻止冒泡
参见红宝书(第4版P525)
- 给子级加上 event.stopPropagation( ),阻止往上冒泡
- 在事件处理函数中返回 false,组织了事件本身(默认事件)
没搞懂
- event.target==event.currentTarget,让触发事件的元素等于绑定事件的元素,也可以阻止事件冒泡;
没搞懂
1.5 ES5,ES6新特性
属于基础知识,不赘述
2.1 flex
- 常见属性:参见阮一峰老师的 http://www.ruanyifeng.com/blo...
- 如何实现类似快手这种视频列表的瀑布流布局(一行两个)
- flex:1的含义:
flex
属性是flex-grow
,flex-shrink
和flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。这里相当于flex:1 1 auto。
flex-grow
属性定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。如果所有项目的flex-grow
属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。flex-shrink
属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。如果所有项目的flex-shrink
属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink
属性为0,其他项目都为1,则空间不足时,前者不缩小。flex-basis
属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。它可以设为跟width
或height
属性一样的值(比如350px),则项目将占据固定空间。
2.2 css动画的实现方式?具体一些
https://zh.javascript.info/js...
2.3 position每种属性的作用
positon和display是前端最重要的两个基本属性,一定得好好写
参见:阮一峰老师的https://www.ruanyifeng.com/bl...
3.11 (this、const/let/var)
在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值:
- 如果是该函数是一个构造函数,this指针指向一个新的对象
- 在严格模式下的函数调用下,this指向undefined
- 如果是该函数是一个对象的方法,则它的this指针指向这个对象
箭头函数出现之后
- 箭头函数表达式的语法比[函数表达式]更简洁,并且没有自己的this,arguments,super或者new.target
- 箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
- 由于 箭头函数没有自己的this指针,通过
call()
或apply()
方法调用一个函数时,只能传递参数(不能绑定this---译者注),他们的第一个参数会被忽略
// Q1 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window
var a = 1;
function print () {
console.log(this.a)
}
print() //a=1
// Q2 如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
const obj = {
a: 2,
print: function () { console.log(this.a) }
}
obj.print(); //2
// Q3
const obj = {
a: 3,
print: function () { console.log(this.a) }
}
obj.print() //3 与下面的foo()区别在于是全局环境还是obj环境
const foo = obj.print;
foo() //undefined 全局情况下调用的,没有全局变量a
// Q3.1 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
const obj = {
a: 3,
printOut:{
a:4,
printIn: function(){ console.log(this.a)},
},
}
obj.printOut.printIn() //4
const foo = obj.printOut.printIn;
foo() //undefined 全局情况下调用的,没有全局变量a
// Q4
const obj = {
a: 4,
print: () => { console.log(this.a) }
}
obj.print(); //undefined 有箭头函数,对象不构成单独的作用域,导致`print`箭头函数定义时的作用域就是全局作用域。
// Q5
var a = 5
const obj = {
a: 6,
print: () => { console.log(this.a) }
}
obj.print.call({a: 7}); //5 理由同上
// Q6
function Person () {
this.a = 8
this.print = function () {console.log(this.a)}
return {a: 9}
}
const p = new Person()
console.log(p.a) //9 此时p为构造函数返回的{a:9}
console.log(p.print()) // undefined p是没有print函数的
// Q7
'use strict';
var a = 1;
function print () {
console.log(this.a)
}
print() //报错 严格模式下,this指向undefined
//考察let,const
// 1.
a = 100;
let a;
a = 10;
function test(num) {
console.log(a);
a = num;
}
console.log(a);
test(5);
console.log(a);
// 2.
const a;
a = 10; //报错
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。