前端面试概念收集器
前端面试三部曲
- 前端面试概念收集器
- 前端面试的经典题
- 前端面试的难题和怪题
本文分为 概念,原生Javascript,css知识点,http协议,网络安全,性能优化。
概念
Commonjs 在Nodejs服务端上运行,无法在浏览器端运行。为了满足浏览器端模块化的要求,才有了AMD和CMD。
AMD (Asynchronous Module Definition)是 RequireJS 在推广过程中对模块定义的规范化产出。对于依赖的模块,AMD 是提前执行。AMD 推崇依赖前置,把依赖参数以数组形式保存在前半部分。使用规则如下:
define(id?, dependencies?, factory);
CMD (Common Module Definition)是 Seajs 在推广过程中对模块定义的规范化产出。 CMD 是延迟执行,CMD 推崇依赖就近,使用规则如下:
define(function(require, exports, module) {
// 模块代码
});
Require.js 和Sea.js都是模块加载器,两者的主要区别如下:
- 定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。Sea.js 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 环境中。
- 遵循的规范不同。RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范。规范的不同,导致了两者 API 不同。Sea.js 更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
- 推广理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。Sea.js 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
- 对开发调试的支持有差异。Sea.js 非常关注代码的开发调试,有 nocache、debug 等用于调试的插件。RequireJS 无这方面的明显支持。
- 插件机制不同。RequireJS 采取的是在源码中预留接口的形式,插件类型比较单一。Sea.js 采取的是通用事件机制,插件类型更丰富。
来自CMD 模块定义规范
UMD (Universal Module Definition),AMD,CommonJS规范是两种不一致的规范,虽然他们应用的场景也不太一致,但是人们仍然是期望有一种统一的规范来支持这两种规范,对两种情况进行判断,兼容两个规范。
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('jquery'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
// methods
function myFunc(){};
// exposed public method
return myFunc;
}));
原生Javascript
在做项目或者产品的过程当中,可能你对框架和库的使用非常多,往往忽视了基础知识。当然,大公司不仅仅希望你是一个api调用工程师,所以对基础知识的考察越来越重要。随着浏览器的兼容性越来越好,原生js的重要性也日益明显。
原生函数
Array
- every() 检测数组所有元素是否都符合指定条件,只要有一个不满足则false。
- some() 检测数组元素中是否有元素符合指定条件,只要有一个满足则true
- concat() 连接两个或更多的数组,并返回结果。
- join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
- pop() 删除并返回数组的最后一个元素
- push() 向数组的末尾添加一个或更多元素,并返回新的长度。
- reverse() 颠倒数组中元素的顺序。
- shift() 删除并返回数组的第一个元素
- slice() 从某个已有的数组返回选定的元素
- sort() 对数组的元素进行排序
- splice() 删除元素,并向数组添加新元素。
Math
- abs(x) 返回数的绝对值。
- acos(x) 返回数的反余弦值。
- asin(x) 返回数的反正弦值。
- atan(x) 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。
- atan2(y,x) 返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间)。
- ceil(x) 对数进行上舍入。
- cos(x) 返回数的余弦。
- exp(x) 返回 e 的指数。
- floor(x) 对数进行下舍入。
- log(x) 返回数的自然对数(底为e)。
- max(x,y) 返回 x 和 y 中的最高值。
- min(x,y) 返回 x 和 y 中的最低值。
- pow(x,y) 返回 x 的 y 次幂。
- random()返回 0 ~ 1 之间的随机数。
- round(x) 把数四舍五入为最接近的整数。
- sin(x) 返回数的正弦。
- sqrt(x) 返回数的平方根。
- tan(x) 返回角的正切。
String
- anchor() 创建 HTML 锚。
- big()用大号字体显示字符串。
- blink() 显示闪动字符串。
- bold() 使用粗体显示字符串。
- charAt() 返回在指定位置的字符。
- charCodeAt() 返回在指定的位置的字符的 Unicode 编码。
- concat() 连接字符串。
- fixed() 以打字机文本显示字符串。
- fontcolor() 使用指定的颜色来显示字符串。
- fontsize() 使用指定的尺寸来显示字符串。
- fromCharCode()从字符编码创建一个字符串。
- indexOf() 检索字符串。
- italics() 使用斜体显示字符串。
- lastIndexOf() 从后向前搜索字符串。
- link() 将字符串显示为链接。
- localeCompare() 用本地特定的顺序来比较两个字符串。
- match()找到一个或多个正则表达式的匹配。
- replace() 替换与正则表达式匹配的子串。
- search() 检索与正则表达式相匹配的值。
- slice()提取字符串的片断,并在新的字符串中返回被提取的部分。
- small() 使用小字号来显示字符串。
- split() 把字符串分割为字符串数组。
- strike() 使用删除线来显示字符串。
- sub() 把字符串显示为下标。
- substr() 从起始索引号提取字符串中指定数目的字符。
- substring() 提取字符串中两个指定的索引号之间的字符。
- sup() 把字符串显示为上标。
原生Javascript求数组最小值和最大值
Math.min.apply(null, array)
Math.max.apply(null, array)
原生Dom操作
- 删除 removeChild 只删除下一级
- 移动 appendChild 捕获一个dom插入
- 复制 cloneNode true 深克隆 false 浅克隆
- 插入 appendChild 新建一个dom插入
- 替换 replaceChild
- 前插后插 insertBefore 后插需要用nextSibling找到下一个节点
查找
- getElementsByTagName() 通过标签名称
- getElementsByName() 通过元素的Name属性的值
- getElementById() 通过元素Id,唯一性
重绘重排
当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘,参考高性能JavaScript DOM编程以及重排与重绘。
事件流(捕获冒泡),参考JavaScript的事件机制
从document开始,到document结束。事件流分为三个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
事件流分为两类:捕获型事件和冒泡型事件。
- 捕获型事件
从根元素向下传播,从body开始往每一个div。方法是addEventListener
。(true:捕获,false:冒泡,默认:false)
- 冒泡型事件
由当前dom向上传播,从div到body。方法是onclick事件
。
委派代理 参考JavaScript事件代理和委托(Delegation)
var delegate = function(client, clientMethod) {
return function() {
return clientMethod.apply(client, arguments);
}
}
var ClassA = function() {
var _color = "red";
return {
getColor: function() {
console.log("Color: " + _color);
},
setColor: function(color) {
_color = color;
}
};
};
var a = new ClassA();
a.getColor();
a.setColor("green");
a.getColor();
console.log("执行代理!");
var d = delegate(a, a.setColor);
d("blue");
console.log("执行完毕!");
a.getColor();
兼容性写法
ie下的兼容性问题,js举例,(转载)IE8+兼容经验小结。
IE6能识别下划线"_"和星号"\ * ",IE7能识别星号" * ",但不能识别下划线"_",IE6~IE10都认识"\9",但firefox前述三个都不能认识。
动画方面,加速度,重力模拟实现
正则,基本用法和相关函数作用
参考深入浅出的javascript的正则表达式学习教程。
必须要死记硬背的事\d
数字,即“digit”,\w
字母,即“word”,\s
空格或tab,即“space”。\D
是非数字字符,\S
是非空白字符,/W
是非单词字符。
{3}
是指有3个这样的字符,{2,3}
至少出现2次但不超过3次,{2,}
至少出现2次。?
指零个或一个,+
指是一个或多个。*
是任意个也可以没有。
定义的方法是
new RegExp(pattern,attributes);
其中,参数pattern是一个字符串,指定了正则表达式的模式;参数attributes是一个可选的参数,包含属性 g,i,m,分别使用与全局匹配,不区分大小写匹配,多行匹配。
也可以是/pattern/
直接定义。方法包含:
- test() 用于检索字符串的指定值。
- exec() 返回找到的值,一般是数组。
- compile() 用于改变RegExp()
OOP
如果你需要补救Javascript面向对象这一方面,先看廖雪峰老师的Javascript原型继承,以及廖雪峰老师的Javascript面向对象编程(二):构造函数的继承。你必须掌握好一个概念就是原型链 。
类继承方法
类的继承有4种方法。比较完美的方法是声明一个空对象,作为中间prototype,参考brandonxiang/example-mocha/demo5。
私有变量
GlobalScope和LocalScope是指面向对象中的共有或私有变量函数,全局变量的搜索较慢,减少document的访问。私有变量和公有变量是Javascript基础开发的一个重要环节。下面是一个简单的例子,name
是公用变量,它是this
的一个属性。age
是一个私有变量,但是它能被对应的公有方法调用。
function Person(props){
this.name ='brandon';
var age = '26';
this.setAge = function(_age){
age = _age;
}
this.getAge = function(){
return age;
}
}
变量提升和函数提示和作用域
一道容易做错的JavaScript面试题很好地讲述了这个问题。
如果你还是不懂。我举几个简单的例子,来自你不知道的Javascript。
变量提升
a=2;
var a;
console.log(a);
结果输出为2。由于var a;
变量提升,提升到代码的顶端,而它不会改变数值。代码怎变成了:
var a;
a=2;
console.log(a);
如果题目情况是下面这样。
console.log(a);
var a = 2;
结果输出是undefined。只有var a;
才会提升。a=2;
并不会提升。
函数提升
foo(); //3
function foo(){
console.log(1);
}
var foo = function(){
console.log(2);
}
foo(); //2
function foo(){
console.log(3);
}
定义为function会直接引起函数提升,提升到文件最上端,第一次foo()
输出2。而且后一个会将前一个覆盖。var foo = function(){}
不会被提升。在后面的函数调用会覆盖,第二次foo()
输出2。
作用域
- 若apply或者call直接作用于对象,this属性必须是该对象
- 方法被提取或者出现
(a=a)()
或(a,a)()
奇葩的调用一般都是上级或者window - 没有var的情况,直接找上级对象
- 箭头函数需特别注意
闭包
参考前端基础进阶(四):详细图解作用域链与闭包
内存泄漏的原因和场景
- 频繁操作iframe
- 动态创建DOM
- 事件绑定
- Ext框架本身
h5里一些新增api的了解H5的新特性及部分API详解
cookie,localstorage和sessionstorage
cookie与localstorage区别
- cookie的大小是受限的
- 请求一个新的页面的时候cookie都会被发送过去
- cookie指定作用域,不可以跨域调用
- cookie是http规范的一部分,localstorage在本地“存储”数据
- localstorage是html5的新特性,所以旧浏览器不一定兼容
localstorage与sessionstorage区别
存储在 localStorage 里面的数据没有过期时间(expiration time),而存储在 sessionStorage 里面的数据会在浏览器会话(browsing session)结束时被清除,即浏览器关闭时。
浏览器的对象模型
- window
- document
- history
- location
- screen
详情参考 《Javascript高级编程》的BOM一章。
CSS知识点
块元素
div center h1 hr table ul ol
内联元素
span a font img strong sub
模型盒
offsetwidth = width + border + padding
clientwidth = width + padding
doctype
html 5 的doctype写法
- 正确使用DOCTYPE
- CS002: DOCTYPE 与浏览器模式分析
haslayout
hack写法参考 史上最全的CSS hack方式一览
link和@import的区别
link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。
link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
link支持使用Javascript控制DOM去改变样式;而@import不支持。
网络安全
XSS
XSS(Cross Site Scripting),是一种注入攻击。没有过滤掉