现在自己会负责项目组的技术面试,正赶上自己也打算投投简历 所以总结点面经用来当题库 嘿嘿嘿~
目前暂时列出我感觉有点营养的题,慢慢填坑,如有不对指出请指出以免误人子弟
基本全程手码 可会出现错字/错行 奇奇怪怪的问题
开始肯定需要 一份详细的自我介绍,通过开发经历总结我的一些优点和开发经验.用简洁明了的方式说明情况,最后说明我从工作中有哪些素质,说明自己可以做什么前端工作.
预留自我介绍位置
一款轻量级mvvm框架,支持双向数据默认为单向数据绑定,上手快,支持库多,基础优化好. 内置了插件/组件/过滤器/指令等方式拓展框架的可用性,支持虚拟DOM(Virtual DOM)提高渲染效率,利用setter/getter实现数据响应
2.1. 利用css3的transform:translate
.box{
/*绝对定位相对父元素50%位置,再利用translate 2D转换平移自身宽高的50%*/
position:absolute;
top:50%;
left:50%;
transform:translate( -50% -50%);
}
2.2.flex布局
/*定义主轴和交叉周为center*/
.box {
display:flex;
justify-content: center;
align-items: center;
}
2.3 用table布局
.box{
/*让元素渲染为表格单元格*/
display:table-cell;
text-align:center;
vertical-align:middle;
}
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
https叫安全的超文本传输协议 ,HTTPS并不是新协议 而是HTTP(TCP:80)协议的安全升级版. 是HTTP(TCP端口:443)中加入SSL层,数据会通过KPI中的公钥进行加密,这样抓包工具捕获数据也没办法进行解密,大大的加强安全性.
闭包是本质是利用外部函数的内部函数引用外部函数内的变量,内部函数可以通过函数作用域链访问到外部函数的变量.形成引用 导致外部函数执行销毁后内部变量因为被内部函数引用无法被销毁.达到保存外部变量的一种方式
优点是可以保护外部变量不被污染,因为外部函数被销毁 无法直接修改
缺点是 不主动释放内部函数的引用 内部变量无法释放 导致内存泄露
NaN : not a number 这是一个特殊值 , 这个数值表示本来要返回数值的操作数未返回数值的情况,
NaN本质还是数字类型的 所以typeof输出还是number
类型 NaN参与任何数字运算返回的都是NaN
NaN不等于任何值包括自己 所以要用ECMAscript中提供的isNaN()
方法来判断运算结果是否是NaN
JavaScript是弱类型语言 声明变量时不用声明类型 虽然在变量没有类型限制 但用运算符对变量进行运算时往往对变量的类型往往有一些要求,所以当运算时会对变量进行转换
显性转换 强制类型转换主要是指通过String、Number和Boolean等构造方法手动转换成对应的字符串、数字和布尔值。
隐性转换
function SuperType(){
this.SuperName = "baba";
}
SuperType.prototype.getSuperValue=function(){
return this.SuperName;
}
function SubType(){
this.SubName = "erzi";
}
//通过创建SuperType的实例继承了SuperType
SubType.prototype=new SuperType();
SubType.prototype.constructor = SuperType;
SubType.prototype.getSubValue=function(){
return this.SubName;
}
var instance=new SubType();
alert(instance.getSuperValue()); //baba
alert(instance.getSubValue()); // erzi
特点
子类如果修改超类引用类型数据会导致超类原型中数据直接变化
子类无法向超类构造函数传参数?
function SuperType(){
this.SuperName = "baba";
}
SuperType.prototype.getSuperValue=function(){
return this.SuperName;
}
function SubType(){
//直接利用call函数 借用构造函数 将this指向构造函数
SuperType.call(this)
this.SubName = "erzi";
}
SubType.prototype.getSubValue=function(){
return this.SubName;
}
var instance=new SubType();
alert(instance.getSuperValue()); //Error
alert(instance.getSubValue()); // erzi
特点
只能继承属性 无法继承超类的方法
function SuperType(){
this.SuperName = "baba";
}
SuperType.prototype.getSuperValue=function(){
return this.SuperName;
}
function SubType(){
//直接利用call函数 借用构造函数 将this指向构造函数
SuperType.call(this)
this.SubName = "erzi";
}
//通过创建SuperType的实例继承了SuperType
SubType.prototype=new SuperType();
SubType.prototype.constructor = SuperType;
SubType.prototype.getSubValue=function(){
return this.SubName;
}
var instance=new SubType();
alert(instance.getSuperValue()); //baba
alert(instance.getSubValue()); // erzi
特点
目前较为常用的继承方法
在原型链继承的基础上 在子类构造函数中借用了超类的构造函数 在子类函数中生成超类的属性 达到在子类中重写效果
function SuperType(){
this.SuperName = "baba";
}
SuperType.prototype.getSuperValue=function(){
return this.SuperName;
}
function SubType(){
//直接利用
this.SuperType = SuperType;
this.SuperType();
delete this.SuperType;
this.SubName = "erzi";
}
SubType.prototype.getSubValue=function(){
return this.SubName;
}
var instance=new SubType();
alert(instance.getSuperValue()); //Error
alert(instance.getSubValue()); // erzi
特点
实现和借用构造函数原理一样 将超类中this指向子类从而实现属性的继承 其他特点和借用构造函数继承是一样的 同样可以和原型继承组合使用
//寄生的工厂函数 参数1 超类构造函数 参数2 子类构造函数
function objectFun(superType,subType){
//创建对象
var prototype = Object.create(superType.prototype);
//增强对象
prototype.constructor = superType;
//指定对象
subType.prototype = prototype;
}
function SuperType(){
this.SuperName = "baba";
}
SuperType.prototype.getSuperValue=function(){
return this.SuperName;
}
function SubType(){
//直接利用call函数 借用构造函数 将this指向构造函数
SuperType.call(this)
this.SubName = "erzi";
}
objectFun(SuperType,SubType)
SubType.prototype.getSubValue=function(){
return this.SubName;
}
var instance=new SubType();
alert(instance.getSuperValue()); //baba
alert(instance.getSubValue()); // erzi
特点
所有组合继承都调用超类构造2次. 寄生组合之调用一次
继承前篇一律分为2类
1是通过原型链把原型上的方法继承下来 实现方法的复用
2是通过构造函数借调(各种其他方法)讲私有属性继承下来
两种方法叠加便是组合继承,所以组合继承几乎完美实现了js的继承.
寄生组合继承目前是最完美的继承方法,因为他只调用一次超类实例
var user = {name: 'tom', age: 20, gender: 'male'}
var test = document.getElementByid('test')
test.onclick = function() {
test.innerHTML = user.name;
}
// ...后面还有很多其他操作,最后把user对象释放掉
user = null; // 释放对象
26.实现一个算法,寻找字符串中出现次数最少的、并且首次出现位置最前的字符
如"cbaacfdeaebb",符合要求的是"f",因为他只出现了一次(次数最少)。并且比其他只出现一次的字符(如"d")首次出现的位置最靠前
var a = b = 2;
/*分割线*/
var a = 2;
var b = 2;
/*两个赋值有什么区别*/
利用移动端touch事件模拟tap事件,
在元素上监听touchstart事件,记录时间和位置 然后在监听touchend事件 判断时间是否超时 位置是否合理来判断用户是否是点击事件,如是 立即触发回调函数,点透是因为touch中同样也会触发click事件.
tap事件的顺序就是 touchstart -> touchmove -> touchend -> 在touchend中执行回
300ms延迟出现的原因
移动端click时间300延迟 因为当时苹果首款iPhone发布,当时web端都是针对大屏幕pc的适配,在当初iphone屏幕中无法得到适配,所以做了一些约定解决移动端适配问题,最有名的就是双击缩放(doule tap to zomm),这也是300毫秒延迟的原因.当用户点击屏幕之后,浏览器就要判断用户是要缩放还是单击,所以浏览器就等待300毫秒 以判断用户是否再次点击屏幕.
FastClick
专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发一个模拟click 事件的click事件(自定义事件),并把浏览器在 300 毫秒之后真正触发的 click 事件阻止掉。
也就是在document.body上绑定了click,touchstart,touchend,touchcancel事件.当点击时冒泡到body中event.preventDefault()阻止默认事件,然后在document.createEvent('MouseEvents') clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
调
var x;
(function(){
x = 2;
y = 2;
})();
console.log(x == y);
//返回值是什么 ???
1.浏览器先查看浏览器缓存-系统缓存-路由器缓存,若缓存中有,直接跳到第8步,
2.解析url中解析出主机名,进行DNS解析
3.解析url端口号,http 80 https 443
4.与服务器三次握手建立tcp链接
5.浏览器通过tcp连接向服务器发送http请求,请求数据包。
6.服务器处理HTTP请求,返回响应。
7.浏览器检查HTTP响应是否为一个重定向(3XX结果状态码)、一个验证请求(401)、错误(4XX、5XX)等等,这些都需要根据具体情况分类处理。
8.浏览器解码响应,如果响应可以缓存,则存入缓存。
9.接收到HTML文档后,遍历文档节点生成DOM树,DOM树生成过程中可能会被CSS JS的加载而阻塞.image标签只会向发出请求并不会阻塞DOM
10.如有CSS标签,DOM构建暂停,浏览器解析CSS文件并生成CSSOM规则树,如有JS阻塞 DOM构建暂停 直至脚本执行完成. 如果js脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建.
11.浏览器通过DOM树和CSSOM规则构建渲染树, 浏览器先从DOM树的根节点开始遍历每个可见节点,对每个可见节点,找到适配的CSS样式规则并应用.渲染树构建完成后每个节点都是可见节点并都包含其内容对应规则的样式这也是渲染树和DOM树的区别
12.布局阶段 浏览器从渲染树的根节点开始遍历然后确定每个节点对象在页面上的确切大小与位置
13.display 之后如果image标签没有固定大小.或者其他事件改变布局 会导致reflow
//执行代码
var obj = new Base();
//剖析 new Base() 做了什么
{
// 创建新对象
var _obj = {};
// 继承原型
_obj.__proto__ = Base.prototype;
// 继承属性
Base.call(_obj)
// 返回对象
return _obj;
}
三者都是用来改变函数执行时函数作用域中this指向的
call apply 借调函数 两者本质没有区别 只是入参不一样
.call(this,arg1,agr2....) || .apply(this,[arg1,arg2])
call/apply都是在使用时直直接调用被借调的函数,并将借调函数中this设置为传入的上下文
bind 绑定函数
.bind(this)
在使用时返回一个新函数,函数内部this被永久绑定为传入上下文
声明自定义事件 (creatEvent dispatchEvent)
creatEvent 创建事件就是根据api支持情况选择api
addEvent: function(type, fn, capture) {
var el = this.el;
if (window.addEventListener) {
el.addEventListener(type, fn, capture);
} else if (window.attachEvent) {
el.attachEvent("on" + type, fn);
}
return this;
}
dispatchEvent
// 创建
var evt = document.createEvent("HTMLEvents");
// 初始化
evt.initEvent("alert", false, false); // (EventName Bubble preventDefault)
// 触发
dom.dispatchEvent(evt);
结尾:
未来三年的职业规划
要学:
计算机网络、操作系统、数据结构课程
要看:
剑指offer 你不知道的JavaScript 望远镜
自勉