前端面试题
Happy coding.
new的原理
function Foo (name, age) {
this.name = name;
this.age = age;
this.class = 'class-1';
// return this // 默认有这一行,new是一种语法糖,
// 它帮我们在每个new Foo()中添加了这一句代码
}
var f = new Foo('z', 22);
// var f2 = new Foo('x', 21);
new操作符具体干了什么呢?
- 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
- 属性和方法被加入到 this 引用的对象中。
- 新创建的对象由 this 所引用,并且最后隐式的返回 this 。
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
如何去判断一个变量是不是数组
isArray = Array.isArray ||
function (obj) {
return obj instanceof Array;
};
什么时候使用==
或===
jQuery源码中,除了判断一个对象是否为空时使用==
,其他任何地方都使用===
if (obj == null) {
// 相当于obj === null || obj === undefined
}
XML和JSON的区别
(1).数据体积方面。
JSON相对于XML来讲,数据的体积小,传递的速度更快些。
(2).数据交互方面。
JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
(3).数据描述方面。
JSON对数据的描述性比XML较差。
(4).传输速度方面。
JSON的速度要远远快于XML。
说说你对作用域链的理解
- 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的;
- 作用域链的变量只能向上访问,变量访问到
window
对象即被终止,作用域链向下访问变量是不被允许的。
渐进增强和优雅降级
渐进增强 :针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级 :一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
创建ajax
过程
- 创建
XMLHttpRequest
对象,也就是创建一个异步调用对象. - 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
- 设置响应HTTP请求状态变化的函数.
- 发送HTTP请求.
- 获取异步调用返回的数据.
- 使用JavaScript和DOM实现局部刷新.
var xhr = new XMLHttpRequest()
xhr.open('GET', url, false)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
alert(xhr.responseText)
}
}
}
xhr.send(null)
对前端模块化的认识
- AMD 是
RequireJS
在推广过程中对模块定义的规范化产出。 - CMD 是
SeaJS
在推广过程中对模块定义的规范化产出。 AMD
是提前执行,CMD
是延迟执行。AMD
推荐的风格通过返回一个对象做为模块对象,CommonJS
的风格通过对module.exports
或exports
的属性赋值来达到暴露模块对象的目的。- CMD模块方式
define(function(require, exports, module) {
// 模块代码
});
谈谈性能优化问题
- 代码层面:避免使用css表达式,避免使用高级选择器(#),通配选择器(*)。
- 缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires- 头,服务端配置Etag,减少DNS查找等
- 请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。
- 请求带宽:压缩文件,开启GZIP,
代码层面的优化
- 用
hash-table
来优化查找 - 少用全局变量
- 用
innerHTML
代替DOM
操作,减少DOM
操作次数,优化javascript
性能 - 用
setTimeout
来避免页面失去响应 - 缓存DOM节点查找的结果
- 避免使用CSS Expression
- 避免全局查询
- 避免使用with(with会创建自己的作用域,会增加作用域链长度)
- 多个变量声明合并
- 避免图片和iFrame等的空Src。空Src会重新加载当前页面,影响速度和效率
- 尽量避免写在HTML标签中写Style属性
移动端性能优化
- 尽量使用css3动画,开启硬件加速。
- 适当使用
touch
事件代替click
事件。 - 避免使用
css3
渐变阴影效果。 - 可以用
transform: translateZ(0)
来开启硬件加速。 - 不滥用Float。Float在渲染时计算量比较大,尽量减少使用
- 不滥用Web字体。Web字体需要下载,解析,重绘当前页面,尽量减少使用。
- 合理使用requestAnimationFrame动画代替setTimeout
- CSS中的属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)会触发GPU渲染,请合理使用。过渡使用会引发手机过耗电增加
- PC端的在移动端同样适用
ES6的了解
- 新增模板字符串(为JavaScript提供了简单的字符串插值功能)、
- 箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值
Inputs=>outputs
。)、 for-of
(用来遍历数据—例如数组中的值。)arguments
对象可被不定参数和默认参数完美代替。ES6
将promise
对象纳入规范,提供了原生的Promise
对象。- 增加了
let
和const
命令,用来声明变量;增加了块级作用域;let命令实际上就增加了块级作用域。 - ES6规定,
var
命令和function
命令声明的全局变量,属于全局对象的属性;let
命令、const
命令、class
命令声明的全局变量,不属于全局对象的属性。还有就是引入module
模块的概念
Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?
<!DOCTYPE>
声明位于文档中的最前面,处于<html>
标签之前。告知浏览器以何种模式来渲染文档。- 严格模式的排版和
JS
运作模式是 以该浏览器支持的最高标准运行。 - 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
DOCTYPE
不存在或格式不正确会导致文档以混杂模式呈现。
一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
分为4个步骤:
- 当发送一个URL请求时,不管这个URL是Web页面的URL还是Web页面上每个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使浏览器获得请求对应的IP地址。
- 浏览器与远程
Web
服务器通过TCP
三次握手协商来建立一个TCP/IP
连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。 - 一旦
TCP/IP
连接建立,浏览器会通过该连接向远程服务器发送HTTP
的GET
请求。远程服务器找到资源并使用HTTP响应返回该资源,值为200的HTTP响应状态表示一个正确的响应。 - 此时,Web服务器提供资源服务,客户端开始下载资源。
请求返回后,便进入了我们关注的前端模块
- 简单来说,浏览器会解析
HTML
生成DOM Tree
, - 其次会根据CSS生成CSS Rule Tree,
- 而
javascript
又可以根据DOM API
操作DOM
- 简单来说,浏览器会解析
GET和POST的区别,何时使用POST?
- GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符
- POST:一般用于修改服务器上的资源,对所发送的信息没有限制。
- GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,
- 也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。
- 然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
Object.prototype.clone = function(){
var o = this.constructor === Array ? [] : {};
for(var e in this){
o[e] = typeof this[e] === "object" ?
this[e].clone() : this[e];
}
return o;
}
说说严格模式的限制
严格模式主要有以下限制:
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 不能使用with语句
- 不能对只读属性赋值,否则报错
- 不能使用前缀0表示八进制数,否则报错
- 不能删除不可删除的属性,否则报错
- 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
- eval不会在它的外层作用域引入变量
- eval和arguments不能被重新赋值
- arguments不会自动反映函数参数的变化
- 不能使用arguments.callee
- 不能使用arguments.caller
- 禁止this指向全局对象
- 不能使用fn.caller和fn.arguments获取函数调用的堆栈
- 增加了保留字(比如protected、static和interface)
设立”严格模式”的目的,主要有以下几个:
- 消除
Javascript
语法的一些不合理、不严谨之处,减少一些怪异行为; - 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的
Javascript
做好铺垫。
- 消除
注:经过测试
IE6,7,8,9
均不支持严格模式。
说说你对AMD和Commonjs的理解
CommonJS
是服务器端模块的规范,Node.js采用了这个规范。CommonJS
规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。AMD
推荐的风格通过返回一个对象做为模块对象,CommonJS
的风格通过对module.exports
或exports
的属性赋值来达到暴露模块对象的目的。
说说你对MVC和MVVM的理解
MVC
- View 传送指令到 Controller
- Controller 完成业务逻辑后,要求 Model 改变状态
- Model 将新的数据发送到 View,用户得到反馈
- 所有通信都是单向的。
Angular
它采用双向绑定(data-binding):View
的变动,自动反映在ViewModel
,反之亦然。- 组成部分Model、View、ViewModel
- View:UI界面
- ViewModel:它是View的抽象,负责View与Model之间信息转换,将View的
Command传送到Model; - Model:数据访问层
cookie
和sessionStorage
localStorage
的区别
容量
前者的最大内存为4KB,后者的最大内存为5MB
是否会携带到
ajax
中前者会被携带到每次请求中,后者不会
API易用性
前者本质是字符串,可以直接从
document.cookie
获取;后者可以通过
localStorage.getItem(key)
、localStorage.setItem(key, value)
存取数据。注:
localStorage.getItem(key)
,在IOS Safari的隐藏模式下会报错;因此,推荐在使用时,用try {} catch (e) {}
捕获错误。