Front-End
前端开发工程师面试宝典! (本文部分有转载,不定期更新!) 
前言(README.md)
1 | 本仓库是我整理的前端常见面试题,大部分由我整理,其中个别部分参考网上其他资料,感谢! |
NO.1 README
NO.2 简历经验分享
NO.3 angular常见问题
NO.4 前端面试宝典第一版
NO.5 前端笔记版本第二版
NO.6 前端笔记版本第三版
NO.7 前端笔记版本第四版
NO.8 vue常见问题
欢迎大家一起交流提高
CSS盒模型
基本概念:标准模型+IE模型
标准模型和IE模型区别
- 标准模型的宽度是content
- IE模型的宽和高是content+padding+border
CSS如何设置这两种模型
- box-sizing:conten-box;用于标准浏览器
- box-sizing:border-box;用于IE浏览器
BFC或IFC(边距重叠解决方案)
BFC:块级格式化上下文
IFC:行内格式化上下文
- BFC的原理:BFC的渲染规则
- 一、BFC的垂直方向边距会发生重叠
- 二、BFC的box区域不会与浮动元素重叠(用于清除浮动)
- 三、BFC在页面上是一个独立的容器,外面的元素不会影响里面的元素
- 四、计算BFC高度的时候浮动元素也会参与计算
如何创建BFC- float不为none(默认值是none)
- position不是static和relative
- display的值是table相关的
- overflow的值不为visible
BFC的使用场景- BFC垂直方向边距重叠
- BFC不与float元素重叠
- BFC子元素即使是float也会参与
##HTTP协议
HTTP协议的主要特点
- 简单快速:每个URI是固定的
- 灵活:可以完成不同数据类型的传输
- *无连接:连接一次就会断掉,不会一直连着
- *无状态:http不能区分两次连接的不同
HTTP报文的组成部分
请求报文
- 请求行(http方法+页面地址+http协议版本)
- 请求头(key:value值)
- 空行(头和体的分隔标识)
- 请求体
响应报文- 状态行(http协议+版本+状态码)
- 响应头
- 空行
- 响应体
HTTP方法
- GET->获取资源
- POST->传输资源
- PUT->更新资源
- DELETE->删除资源
- HEAD->获得报文首部
POST和GET的区别
- GET在浏览器回退时是无害的,而POST会再次提交请求
- GET产生的URI地址可以被收藏,而POST不可以
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会保留
- GET请求在URL中传输的参数是有长度限制的,而POST没有限制
- GET参数通过URL传递,POST放在Request body中
常见HTTP状态码
- 1xx:指示信息-表示请求已接收,继续处理
- 2xx:成功-表示请求已被成功接收
- 3xx:重定向-要完成请求必须进行更进一步的操作
- 4xx:客户端错误-请求有语法错误或请求无法实现
- 5xx:服务器错误-服务器未能实现合法的请求
- 200:服务器成功返回
- 206:客户端表明自己只需要目标URL上的部分资源
- 301:永久重定向
- 302:临时重定向
- 304:缓存(服务器告诉客户,原来缓冲的文档还可以继续使用)
- 400:请求出错
- 401:被请求的页面需要用户名和密码
- 403:服务器拒绝访问
- 404:资源找不到
- 500:服务器错误
- 503:请求未完成。服务器临时过载或当机
HTTPS对于HTTP的优点
- 通信使用明文不加密,内容可能被窃听
- 不验证通信方身份,可能遭到伪装
- 无法验证报文完整性,可能被篡改
HTTPS就是HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护
##关于this
浏览器宿主的全局环境中,this指的是window对象。1
console.log(this === window); //true
浏览器中在全局环境下,使用var声明变量其实就是赋值给this或window。1
2
3var foo = "bar";
console.log(this.foo); //logs "bar"
console.log(window.foo); //logs "bar"
任何情况下,创建变量时没有使用var或者let(ECMAScript 6),也是在操作全局this。1
2
3
4
5
6
7
8
9foo = "bar";
function testThis() {
foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis();
console.log(this.foo); //logs "foo"
除了DOM的事件回调或者提供了执行上下文(后面会提到)的情况,函数正常被调用(不带new)时,里面的this指向的是全局作用域。
当用调用函数时使用了new关键字,此刻this指代一个新的上下文(实例),不再指向全局this。
在DOM事件的处理函数中,this指代的是被绑定该事件的DOM元素。
HTML标签的属性中是可能写JS的,这种情况下this指代该HTML元素。
- 无法重写this,因为它是一个关键字。
##通信类
什么是同源策略及限制
- 源:协议,域名,端口
- 限制:不是一个源的文档没有权利去操作另一个源的文档,包括:Cookie, LocalStorage, IndexDB,DOM无法获取, Ajax无法发送
- 同源策略限制不同的源的文档之间进行交互
前后端如何通信
- ajax(同源限制)
- WebSocket(不受限制)
- CORS(支持同源,也支持非同源—新的通信协议标准)
跨域通信的几种方式
- JSONP
- Hash(hash改变,页面是不刷新的,?后是search,改变时会刷新页面)
- postMessage(H5标准)
- WebScoket
- CORS(可以理解为支持跨域通信的变种Ajax。当你在浏览器中发送一个ajax跨域请求时,浏览器会在http头中加入一个origin。如果只是一个普通的ajax,则会被浏览器拦截)
JSONP的原理:利用script标签可以实现加载不同源。
- 在window全局注册一个函数
- 给服务端传递这个函数的名字,同时可以有参数
- 服务端返回这个函数,内部填充有数据,就可以拿到数据
- 删除全局注册的那个函数
Hash的原理:页面A中通过iframe或iframe嵌入了B窗口。目标是A给B发送消息。
- 拿到B的url地址
- 改变其hash值
- 在B中接收,onhashchange
WebSocket的原理:
- var ws = new WebSocket(‘wss:echo.websocket.org’);
- onopen, onmessage, onclose
##浏览器是怎样渲染一个页面
由从服务器接收到的 HTML 形成DOM(文档对象模型)。
样式被加载和解析,形成 CSSOM(CSS 对象模型)。
紧接着 DOM 和 CSSOM 创建了一个渲染树,这个渲染树是一些被渲染对象的集合( Webkit 分别叫它们”renderer”和”render object”,而在Gecko 引擎中叫”frame”)。除了不可见的元素(比如 head 标签和一些有 display:none 属性的元素),渲染树映射了 DOM 的结构。在渲染树中,每一个文本字符串都被当做一个独立的 renderer。每个渲染对象都包含了与之对应的计算过样式的DOM 对象(或者一个文本块)。换句话说,渲染树描述了 DOM 的直观的表现形式。
对每个渲染元素来说,它的坐标是经过计算的,这被叫做“布局(layout)”。浏览器使用一种只需要一次处理的“流方法”来布局所有元素(tables需要多次处理)。
最后,将布局显示在浏览器窗口中,这个过程叫做“绘制(painting)”。
重绘
当在页面上修改了一些不需要改变定位的样式的时候(比如background-color,border-color,visibility),浏览器只会将新的样式重新绘制给元素(这就叫一次“重绘”或者“重新定义样式”)
重排
当页面上的改变影响了文档内容、结构或者元素定位时,就会发生重排(或称“重新布局”)。重排通常由以下改变触发:
DOM 操作(如元素增、删、改或者改变元素顺序)。
内容的改变,包括 Form 表单中文字的变化。
计算或改变 CSS 属性。
增加或删除一个样式表。
改变”class”属性。
浏览器窗口的操作(改变大小、滚动窗口)。
激活伪类(如:hover状态)。
##加载和渲染过程
页面加载和渲染的过程(涉及内核间的差异以及并发处理)
从浏览器地址栏的请求链接开始,浏览器通过DNS解析查到域名映射的IP地址,成功之后浏览器端向此IP地址取得连接,成功连接之后,浏览器端将请 求头信息 通过HTTP协议向此IP地址所在服务器发起请求,服务器接受到请求之后等待处理,最后向浏览器端发回响应,此时在HTTP协议下,浏览器从服务器接收到 text/html类型的代码,浏览器开始显示此html,并获取其中内嵌资源地址,然后浏览器再发起请求来获取这些资源,并在浏览器的html中显示。
其实浏览器加载显示html的顺序是按下面的顺序进行的:
1、IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。
2、在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都已经下载完)。
3、如果遇到语义解释性的标签嵌入文件(JS脚本,CSS 脚本)在IE的下载过程会启用单独连接进行下载。
4、并且在下载后进行解析,解析过程中,停止页面所有往下元素的下载。
5、样式表在下载完成后,将和以前下载的所有样式表一起进行解析,解析完成后,将对此前所有元素(含以前已经渲染的)重新进行渲染。
6、JS、CSS中如有重定义,后定义函数将覆盖前定义函数。
Firefox处理下载和渲染顺序大体相同,只是在细微之处有些差别,例如:iframe的渲染
样式文件和JS文件一样是下载完一个解析一个的
##运算符
i++和 ++i的区别,i++单独使用时候和++i一模一样,i++是等i这个表达式运算结束后再运算i+1,然后改变i的值,
而++i是先运算i+1,然后改变i的值,然后再和外面的表达式结合,进行整体运算。
##字符串处理
toFixed(num)(ps:num为保留小数点后几位)
Math.ceil(num) //返回大于等于其数值参数的最大整数
Math.floor(num) //返回小于等于其数值参数的最大整数
Math.round(num) //四舍五入取整
concat 将两个或多个字符的文本组合起来,返回一个新的字符串。
indexOf 返回字符串中一个子串第一处出现的索引(从左到右搜索)。如果没有匹配项,返回 -1 。
charAt 返回指定位置的字符。
lastIndexOf 返回字符串中一个子串最后一处出现的索引(从右到左搜索),如果没有匹配项,返回 -1 。
match 检查一个字符串匹配一个正则表达式内容,如果么有匹配返回 null。
substring 返回字符串的一个子串,传入参数是起始位置和结束位置。
substr 返回字符串的一个子串,传入参数是起始位置和长度
replace 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。
search 执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值。否则返回 -1 。
slice 提取字符串的一部分,并返回一个新字符串(与 substring 相同)。
split 通过将字符串划分成子串,将一个字符串做成一个字符串数组。
length 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。
toLowerCase 将整个字符串转成小写字母。
toUpperCase 将整个字符串转成大写字母。
字符串连接操作非常消耗资源,解决方法是用 Array 对象存储字符串,然后用 join() 方法(参数是空字符串)创建最后的字符串
##js里面的基础对象和基础数据类型
JS基础数据类型:number数字(NaN)、string字符串、boolean布尔值、null、undefined
typeof 用来判断数据类型
显示/强制类型转换( Number()、parseInt()、parseFloat() )
基础对象:Document、Window、Navigator、Screen、History、Location
基础对象
JS Array、JS Boolean、JS Date、JS Math、JS Number、JS String、JS RegExp、JS Functions、JS Events
Browser 对象 Window、Navigator、Screen、History、Location
##DOM年份,DOM好处和坏处,怎么禁用DOM
Document Object Model (DOM)是HTML和XML文档的编程接口。
DOM标准主要要为:微软DOM与W3C DOM,一般IE实现的是微软DOM,而其它浏览器则不同程度的实际了W3C DOM
DOM Level Zero ,事实上从来不存在DOM 0版本,只是人们的戏称。只是在W3C DOM出现之前,不同浏览器(主要是IE与NN)实现的DOM相互排斥,1996年的浏览器大战所产生的DHTML就是所谓的DOM 0,它是脚本程序员的恶梦
DOM Level 1 包括DOM Core和DOM HTML。前者提供了基于XML的文档结构图。后者添加了一些HTML专用的对象和方法,从而扩展了DOM Core.目前IE在内的大部分桌面浏览器都通过不同方式实现了DOM 1
DOM Level 2 引入几个新模块:DOM视图,事件,样式,遍历和范围。IE只实现了一部分,火狐浏览器几乎全部实现,除IE之外的浏览器也实现了大部分
DOM Level 3 引入了以统一的方式载入和保存文档的方法。DOM Core被扩展支持所有的XML1.0的特性。火狐浏览器之类实现了少部分
好处:js调用dom的属性和方法就可以编程控制网页中的各种元素
坏处:DOM操作很耗性能
##BOM浏览器信息
BOM是Browser Object Model的缩写,简称浏览器对象模型
window对象、History对象、Location 对象、Navigator对象
##Jsonp接口的原理
JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
##js模板引擎
模板引擎是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
JS的加载
不能并行下载和解析(阻塞下载)
当 引用了JS的时候,浏览器发送1个jsrequest就会一直等待该request的返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代 码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现。
##闭包
了解什么是闭包、如何使用闭包、闭包的原理、闭包的真正原理
定义
闭包是有权访问另一个函数作用域中的变量的函数
作用域链
作用域链就是函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引,而他内部的规则是,把函数自身的本地变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止。
内存回收机制
如果这个函数内部又嵌套了另一个函数,而这个函数是有可能在外部被调用到的.并且这个内部函数又使用了外部函数的某些变量的话.这种内存回收机制就会出现问题.
闭包作用:一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
##事件绑定
为什么用bind来进行事件绑定,live方法的实现原理
Jquery中绑定事件有三种方法:以click事件为例
(1)target.click(function(){});
(2)target.bind(“click”,function(){});
(3)target.live(“click”,function(){});
第一种方法很好理解,其实就和普通JS的用法差不多,只是少了一个on而已
第二、三种方法都是绑定事件,但是二者又有很大的不同,下面着重讲解一下,因为这个如果用到Jquery的框架的话是用的挺多的,尤其要注意二者的区别。
【bind和live的区别】
live方法其实是bind方法的变种,其基本功能就同bind方法的功能是一样的,都是为一个元素绑定某个事件,但是bind方法只能给当前存在的元素绑定事件,对于事后采用JS等方式新生成的元素无效,而live方法则正好弥补了bind方法的这个缺陷,它可以对后生成的元素也可以绑定相应的事件。
live方法之所以能对后生成的元素也绑定相应的事件的原因归结在“事件委托”上面,所谓“事件委托”就是指绑定在祖先元素上的事件可以在其后代元素上进行使用。live方法的处理机制就是把事件绑定在DOM树的根节点上,而不是直接绑定在某个元素上。
由于只有在事件发生的时候,live方法才会去检测绑定事件的对象是否存在,所以live方法可以实现后来新增的元素也可实现事件的绑定。相比之下,bind会在事件在绑定阶段就会判断绑定事件的元素是否存在,而且只针对当前元素进行绑定,而不是绑定到父节点上。
那么为什么还要使用bind方法呢?bind和live主要的不同如下:
(1)bind方法可以绑定任何JavaScript的事件,而live方法在jQuery1.3的时候只支持click, dblclick, keydown, keypress,keyup,mousedown, mousemove, mouseout, mouseover, 和 mouseup.在jQuery 1.4.1中,甚至也支持 focus 和 blue事件了(映射到更合适,并且可以冒泡的focusin和focusout上)。另外,在jQuery 1.4.1中,也能支持hover(映射到”mouseenter mouseleave”)。
(2)live() 并不完全支持通过DOM遍历的方法找到的元素。取而代之的是,应当总是在一个选择器后面直接使用 .live()方法。
(3)当一个元素采用live方法进行事件的绑定的时候,如果想阻止事件的传递或冒泡,就要在函数中return false,仅仅调用stopPropagation()是无法实现阻止事件的传递或者冒泡的
##mouseover和mouseenter的区别
- 不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件。对应mouseout
- 只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件。对应mouseleave
工具库
extJS、YUI、Prototype:这些工具库或框架都有各自的特点
- extJS
最新版本:Ext JS5
优点: 强大的UI,而且性能不错,这是其最大的优点。 速度快,不管是UI还是其它模块。 100%面向对象和组件化的思想,一致的语法,全局的命名空间。 文档的完整,规范,方便。 核心的开发团队,Jack Slocum等。 活跃的社区,迅速增加的用户量。 模块化实现,可扩展性强。 所有的组件(widgets)都可直接使用,而无需进行设置
缺点: 稍复杂。 为重量级的框架(包含大量UI),体积大。如果导入ext-all.js,压缩后也有近500k。
2.ExtJs的特点
(1)纯Html/CSS+JS技术,重新定义表示层的耦合;
(2)基于纯Html/CSS+JS技术,提供丰富的跨浏览器UI组件,灵活采用JSON/XML数据源开发,使得服务端表示层的负荷真正减轻,从而达到客户端的MVC应用;
(3)集成多种JS底层库, 满足开发者不同需求;
(4)Ext初期仅是对YUI的对话框扩展,后来逐渐有了自己的特色,深受网友的喜爱。发展至今,Ext除YUI外还支持Jquery Prototype等的JS库,让大家自由地选择;
(5)多浏览器支持、支持多平台下的主流浏览器。
3.ExtJs的优缺点
(1).ExtJs的优点
<1>.UI组件丰富,外观漂亮。1>
Ext JS库有着丰富且漂亮的UI组件,大大缩短了我们的开发周期,而且组件拥有漂亮的布局,经过简单的调用与配置就可以实现不错的界面布局。ExtJS提供的各种组件可以用更加标准的方式展示数据降低了开发难度。
<2>.浏览器兼容性好。2>
使用ExtJS对浏览器没有任何要求。可以说是一种绿色的富客户端实现方式,ExtJs基本可以运行于现在主流的浏览器。
<3>有很多动画效果做得很不错,提高了用户的感知度。3>
<4>和后台代码无关。4>
不管后台用什么语言开发的都不会受影响,不管你是用C#也好 JAVA也好 还是PHP都和它没关系。
<5>将Web程序向桌面系统转化。5>
ExtJS最大的优势在于它将Web应用程序的操作方式向传统桌面应用程序的操作方式进行转化甚至消除了这种差异,从根本上提高了用户的使用体验,这是ExtJS应用前景广阔的主要原因。
<6>.相对丰富的文档和示例。6>
毫无疑问,刚刚接触到ExtJS的人多数都是被它附带的例子和开发文档吸引过去的,它的文档做的确实不错。
(2) ExtJs的缺点
<1>.体积较大,速度稍慢。1>
由于使用了大量的UI组件,所以体积较大,导致页面加载速度比较慢。
<2>.收费,好像不免费。2>
因为它太优秀了,所以从Ext JS 2.0以后的版本都是收费的。也许这一点不能算是它的缺点,但这确实阻碍了它的推广与应用。
<3>没有合适的开发利器。3>
毫无疑问,一个好的开发工具可以大大的提高编码的速度,但是对于ExtJS,始终没有一个完美的开发工具,可以推荐的有Aptana Studio, Spket IDE,和Spket 提供的提示文件,但是都是各有优缺点,都不完美,只能一边看SDK一边写代码。
<4>没有界面设计工具。4>
虽然有人提供了一个在线的界面设计工具,但是和Visual Studio提供的ASP.Net设计工具来说,真的可以说是天壤之别。因此,只能一边预览,一边写代码。
<5>文档不全。5>
虽然ExtJS提供的文档很丰富,但是还是跟不上源代码的更新速度,所以,经常要通过看源代码,调试才能真正解决问题。
<6>不能编译。6>
这一点可以说是JavaScript的缺点(如果能编译,就不叫JavaScript了),在实际的开发中,经常会敲错一些代码,比如大小写错误等,不能通过编译得到反馈,只能在运行时排错,导致开发的效率比较低下。
YUI
如果你想作门户、如果你想作SNS、如果你想作大型电子商务和电子政务网站,你大概只有一个选择,那就是Yui,Yui抽象出了比其他框架更复杂的层次结构、把模块按照不同的层次划分,并定义层次之间模块依赖关系,这种设计使得Yui对万行级代码的管理游刃有余,这种重设计轻开发的思想是Yui的核心之一,此外,Yui不仅仅是JS框架,他是JS+CSS+规范的集合,必要的约束在团队协作项目中可以降低成本。其实Yui本身也是团队合作的产物。在扩展性方面,我觉得Yui是所有前端框架作的最好的,Ext就是选择基于Yui进行扩展。相对来讲,ProtoType和jQuery显然太小了。Prototype
优点:基本底层,易学易用,甚至是其他一些js特效开发包的底层,体积算是最小的了。
缺点:如果说缺点,可能就是功能是他的弱项
- jQuery
有人说jQuery是被设计用来改变你写JavaScript的方法的。在这一方面jQuery的确作的很好,20行的Dom javascript语句在jQuery里只需要2-3行就可以完成,语言的简洁简直太吸引人了,尤其对于前端开发工程师这群多少有些代码洁癖的人来说,简直美妙绝伦,甚至忽视了其粗糙的面向对象的结构这一致命的缺点。当我们过多的沉浸在代码简洁的乐趣中无法自拔的时候,对更高级抽象的忽视往往阻挡住了我们的视野。因此,jQuery本身无法承担庞大的网站架构任务,也只能在中小网站中搞一搞动画特效而已。但这仍然无法阻止wd们对jQuery的偏爱,只要你有洁癖,那么你一定会喜欢jQuery的。
- MooTools
在面向对象的方面,MooTools的确作的不错,软件设计模式中的高内聚和低耦合在MooTools中有良好的体现。文档也很完整,但MooTools的占有率一直不高是一个很尴尬的现象,作底端太多余,无法和jQuery竞争,作高端又有点吃力,无法和Yui竞争,给人鸡肋的感觉,就这样。
- fiddler工具
它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据
原理:Fiddler 是以代理web服务器的形式工作的,它使用代理地址:127.0.0.1, 端口:8888. 当Fiddler会自动设置代理, 退出的时候它会自动注销代理,这样就不会影响别的程序。
- BackboneJS
Backbone 为复杂Javascript应用程序提供模型(models)、集合(collections)、视图(views)的结构。其中模型用于绑定键值数据和自定义事件;集合附有可枚举函数的丰富API; 视图可以声明事件处理函数,并通过RESRful JSON接口连接到应用程序。
AngularJS
AngularJS 是一款开源 JavaScript 函式库,由Google 维护,用来协助单一页面应用程式运行的。它的目标是透过MVC模式 (MVC) 功能增强基于浏览器的应用,使开发和测试变得更加容易。
函式库读取包含附加自定义(标签属性)的HTML, 遵从这些自定义属性中的指令,并将页面中的输入或输出与由JavaScript变量表示的模型绑定起来。这些JavaScript变量的值可以手工设置,或者从静态或动态JSON资源中获取。
优点
模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令是一个比较完善的前端MV*框架,包含模板,数据双向绑定,路由,模块化,服务,依赖注入等所有功能
自定义Directive,比jQuery插件还灵活,但是需要深入了解Directive的一些特性,简单的封装容易,复杂一点官方没有提供详细的介绍文档,我们可以通过阅读源代码来找到某些我们需要的东西,如:在directive使用 $parse
ng模块化比较大胆的引入了Java的一些东西(依赖注入),能够很容易的写出可复用的代码,对于敏捷开发的团队来说非常有帮助,我们的项目从上线到目前,UI变化很大,在摸索中迭代产品,但是js的代码基本上很少改动
补充:Angular支持单元测试和e2e-testing
缺点
验证功能错误信息显示比较薄弱,需要写很多模板标签,没有JQuery Validate方便,所以我们自己封装了验证的错误信息提示,详细参考 why520crazy/w5c-validator-angular · GitHub
ngView只能有一个,不能嵌套多个视图,虽然有 angular-ui/ui-router · GitHub 解决,但是貌似ui-router 对于URL的控制不是很灵活,必须是嵌套式的(也许我没有深入了解或者新版本有改进)
对于特别复杂的应用场景,貌似性能有点问题,特别是在Windows下使用chrome浏览器,不知道是内存泄漏了还是什么其他问题,没有找到好的解决方案,奇怪的是在IE10下反而很快,对此还在观察中
这次从1.0.X升级到1.2.X,貌似有比较大的调整,没有完美兼容低版本,升级之后可能会导致一个兼容性的BUG,具体详细信息参考官方文档 AngularJS ,对应的中文版本:Angular 1.0到1.2 迁移指南
ng提倡在控制器里面不要有操作DOM的代码,对于一些JQuery 插件的使用,如果想不破坏代码的整洁性,需要写一些directive去封装一下JQ插件,但是现在有很多插件的版本已经支持Angular了,如:jQuery File Upload Demo
Angular 太笨重了,没有让用户选择一个轻量级的版本,当然1.2.X后,Angular也在做一些更改,比如把route,animate等模块独立出去,让用户自己去选择
- Seajs
SeaJS是由支付宝前端高级技术专家王保平(玉伯)开发的一个遵循CMD规范的模块加载框架,可用来轻松愉悦地加载任意JavaScript模块和CSS模块。 SeaJS非常小巧,小巧在于其压缩后体积只有4KB,而且接口和方法也非常少。SeaJS有两个核心:模块的定义和模块的加载。SeaJS可以加载任意 JavaScript模块和CSS模块,能保证你在使用一个模块时,已将所依赖的其他模块载入脚本运行环境中。SeaJS可以让你享受写代码的乐趣,不用 去管那些加载的问题。毕竟现在网页的可维护性和性能问题一样严峻,体现在:文件太多,不利于维护,前端后端都一样;HTTP请求过多,当然这个可以通过合 并解决,但如果没有后端直接合并,那么人工成本会非常大。用SeaJS就能非常好地解决这些问题。SeaJS遵循CMD规范,因此可以很方便地书写模块。 目前已经有越来越多的人采用CMD规范来开发项目了。
- CommonJS
CommonJS API定义很多普通应用程序(主要指非浏览器的应用)使用的API,从而填补了这个空白。它的终极目标是提供一个类似Python,Ruby和Java标准库。这样的话,开发者可以使用CommonJS API编写应用程序,然后这些应用可以运行在不同的JavaScript解释器和不同的主机环境中。在兼容CommonJS的系统中,你可以实用JavaScript程序开发:
服务器端JavaScript应用程序
命令行工具
图形界面应用程序
混合应用程序(如,Titanium或Adobe AIR)
##lazyloader
1、获取需要做按需加载的图片在页面的位置
getClientRects常用于获取鼠标的位置
getBoundingClientRect获取元素位置
2、预加载的位置为:上下一屏的图片
##cookie
大多数浏览器规定Cookie大小不超过4K,每个站点能保存的Cookie不超过20个,所有站点保存的Cookie总和不超过300个
当没有指明cookie时间时,所创建的cookie有效期默认到用户浏览器关闭止,故被称为会话cookie
document.cookie=”userId=828; userName=hulk”;
##描述一下渐进增强和优雅降级之间的不同
两者区别的关键在于它们各自关注的焦点,以及这种关注对工作流程的影响。
优雅降级的视角
优雅降级关注于在最先进/最全能的浏览器上构建网站。在被认为老的或能力不足的浏览器中的测试,经常要等到开发周期的最后一个环节才进行,并且通常限制在主流浏览器(如IE、Mozzila等)的前一个发布版本中。
在这种模式下,老的浏览器只可能提供差强人意(poor, but passable)的体验。或许会做些小补丁来适应某个特定浏览器,但这些浏览器毕竟不是关注的焦点,除了修正重大的错误,也不会再费多大的神了。
渐进增强的视角
渐进增强关注于内容。请注意区别:我甚至都没提及浏览器。
内容是我们最初创建网站的原因。有些网站传播内容,有些收集内容,有些请求内容,有些操作内容,有些网站以上所有功能都有,然而而他们都需要内容。这就是渐进增加成为一种更适合的模式的关键所在。这也是Yahoo!迅速采纳这种模式并用它创建了分级浏览器支持(Graded Browser Support)策略的原因。
##如何无刷新图片上传并且兼容
1、用iframe上传
在页面动态创建 form 表单和 ifram ,设定 form 表单提交的目标为 ifram ,将文件域和要 post 的参数动态写入 form 表单中,然后提交 from 表单
2、借助于flash,例如swfupload.js
##前端自动化工具的区别
比如百度的fix工具和grunt工具
Grunt 是一个基于 task 的构建工具,依赖众多的插件进行配置组织,可以解决基本的前端自动化问题。FIS 是基于工具、开发框架、本地开发环境为一体的前端解决方案,不但拥有各类工具插件,同时还针对 PC、Mobile、I18n 等业务、场景总结了很多最佳实践。
Grunt的缺点
1、相对的低效:grunt各插件之间尽可能地保持独立,于是频繁的文件读写有时候就成了无奈的选择
2、缺乏有效的串联:插件A、插件B之间彼此独立,有的时候需要将插件A的输出,作为插件B的输入(如将sass编译后再内联到html里),有的时候就不得不使用临时目录来曲折地实现这个目的
接触fis是在grunt之后,有两点比较吸引的,当然就是相对于grunt来说:
1、更加高效:管道操作,避免了频繁的文件IO
2、更加灵活的配置:强大到令人发指的部署配置(当然也让人晕晕的,glob、正则混搭的规则~)
##PNG8和PNG24有什么不同
PNG8不支持半透明、PNG24支持半透明
#javascript的typeof返回那些数据类型?
Object number function boolean underfind
IE和DOM事件流的区别
1.执行顺序不一样、
2.参数不一样
事件侦听函数的区别
ie–>attachEvent(‘事件’,事件处理函数);//两个参数
DOM–>addEventListener(‘事件’,事件处理函数,boolean);//三个参数
3.事件加不加on
4.this指向问题
事件绑定:addEventListener
与attachEvent 事件处理函数中this指向不同, IE中指向window
5 ie 捕获 html>div>button
dom 先捕获 在 冒泡 html>div>button>div>html
#call和apply的区别
相同: call和apply 都是为了改变函数体内this的指向的。
不同:接收参数的方式
apply ↓↓↓
function.apply(obj,args)方法能接收两个参数
第一个参数 就是this的指向 这个对象代替Function类里的this对象
args:这个数组或类数组,apply方法把这个集合中的元素作为参数传递给被调用的函数。
call ↓↓↓
call和apply方法的第一个参数是一样的,都是this的指向 功能和this想同
call的第二个参数是参数列表
在非严格模式下当我们第一个参数传递为null或undefined时,函数体的this会指向默认的宿主对象,
在浏览器中则是window
var test = function(){
console.log(this === window);
}
test.apply(null);//true
test.call(undefined);//true
事件委托是什么
让利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!
如何阻止事件冒泡和默认事件
阻止事件冒泡:
stopPropagation()
concelBubble = true //ie用
为了兼容
封装一个stopBubble();
判断浏览器 是否 有 stopPropagation()这个方法
如果有就调用 stopPropagation();
如果不存在 就 调用ie的concelBubble = “true”方法;
阻止默认事件:
proventDefault()
returnValue() //ie用
为了兼容:
封装一个 stopDefault();
判断浏览器 是否 有 proventDefalut()这个方法
如果有就调用 proventDefalut();
如果没有就使用ie的 returnValue = “false”;
闭包是什么,有什么特性,对页面有什么影响
闭包: 闭包的实质是一个函数,是一个用于返回局部变量值的函数,
闭包特性 : 是能够读取其他函数内部变量的函数 因为在全局中,受JavaScript链式作用域结构的影响,父级变量中无法访问到子级的变量值,为了解决这个问题,才使用闭包这个概念。
影响: 由于闭包时,变量的值都保存到内存中,会导致页面加载时内存消耗很大,IE会导致内在泄露,因此尽量少用或用时要及时删除变量。
#doccument load 和 document ready的区别
1.load是当页面所有资源全部加载完成后(包括DOM文档树,css文件,js文件,图片资源等),执行一个函数
问题:如果图片资源较多,加载时间较长,onload后等待执行的函数需要等待较长时间,所以一些效果可能受到影响
2.$(document).ready()是当DOM文档树加载完成后执行一个函数 (不包含图片,css等)所以会比load较快执行
在原生的jS中不包括ready()这个方法,只有load方法就是onload事件
”==”和“===”的不同
==: 比较值是否相同 前者会自动转换类型
===: 比较值与数据类型是否相同 后者不会
#JavaScript 的数据类型都有什么?
1 Number 数字类型
2 String 字符串类型
3 Boolean 布尔类型
4 Function 函数
5 Object 对象
6 Null
7 Undefined 没有定义类型
#简述列举文档对像模型BOM里document 的常用 的查找访问节点 的方法 并作简单 的 说明
1 通过ID,使用 getElementById() 获得标签节点
2 通过标签的名称,使用getElementsByTagName() 获得元素节点或标签节点
注意:以上的查找方式都会忽略文档的结构
3 通过使用一个元素节点的 parentNode、firstChild 以及 lastChild 属性
4 节点名称nodeName
a) 如果节点是标签,nodeName是标签名称
b) 如果节点是属性,nodeName是属性名称
c) 如果节点是文本节点,nodeName是#text
d) 如果节点是文档,nodeName是#document
5 节点值nodeValue
6 节点类型nodeType
#简述创建函数的几种方式
1 函数声明
:解析器会先读取函数声明,并使其在执行任何代码之前可以访问
function sum1(n1,n2){
return n1+n2;
};
2 函数表达式,又叫函数字面量
:函数表达式则必须等到解析器执行到它所在的代码行才会真正被解释执行
var sum2=function(n1,n2){
return n1+n2;
};
3 自执行函数严格来说也叫函数表达式
:创建一个新的作用域,且立即执行,在此作用域内声明的变量,不会和其它作用域内的变量冲突或混淆,大多是以匿名函数方式存在
(function(n1,n2){
console.log (n1+n2)
})(1,3);//4
#JavaScript如何实现继承?
种类:六种 记住前三种 后面三种 记住名称就行
既然要实现继承,那么首先我们得有一个父类,代码如下:
//定义一个动物类
function Animal (name) {
this.name = name || 'Animal'; // 属性
this.sleep = function(){ // 实例方法
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
一 原型链继承(推荐★★ 3 4两大致命缺陷)
核心: 将父类的实例作为子类的原型
特点:
1 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
2 父类新增原型方法/原型属性,子类都能访问到
3 简单,易于实现
缺点:
1 要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
2 无法实现多继承
3 来自原型对象的引用属性是所有实例共享的(详细请看附录代码: 示例1)
4 创建子类实例时,无法向父类构造函数传参
二 组合继承(推荐★★★★(仅仅多消耗了一点内存))
核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
特点:
1 弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
2 既是子类的实例,也是父类的实例
3 不存在引用属性共享问题
4 可传参
5 函数可复用
缺点:
1 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
function Cat(name){
Animal.call(this);
this.name = name || ‘Tom’;
}
Cat.prototype = new Animal();
三 寄生组合继承(推荐 ★★★★(实现复杂,扣掉一颗星))
核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
特点:
堪称完美
缺点:
实现较为复杂
function Cat(name){
Animal.call(this);
this.name = name || ‘Tom’;
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})();
四 构造函数(推荐★★ 缺点3)
核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
特点:
1 解决了1中,子类实例共享父类引用属性的问题
2 创建子类实例时,可以向父类传递参数
3 可以实现多继承(call多个父类对象)
缺点:
1 实例并不是父类的实例,只是子类的实例
2 只能继承父类的实例属性和方法,不能继承原型属性/方法
3 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
function Cat(name){
Animal.call(this);
this.name = name || ‘Tom’;
}
五 实例继承(推荐★★)
核心:为父类实例添加新特性,作为子类实例返回
特点:
1 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
缺点:
1 实例是父类的实例,不是子类的实例
2 不支持多继承
function Cat(name){
var instance = new Animal();
instance.name = name || ‘Tom’;
return instance;
}
六 拷贝继承(推荐★)
特点:
1 支持多继承
缺点:
1 效率较低,内存占用高(因为要拷贝父类的属性)
2 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name || ‘Tom’;
}
#JavaScript创建对象的几种方式?
说明:很多问题 都有很多方式解决 但常用的就一两种 对其他的几种只需要理解就好了
1 对象字面量的方式{} 创建一个对象(最简单,好理解,推荐使用)
var Cat = {};//JSON
Cat.name=”kity”;//添加属性并赋值
Cat.age=2;
Cat.sayHello=function(){
alert(“hello “+Cat.name+”,今年”+Cat[“age”]+”岁了”);//可以使用“.”的方式访问属性,也可以使用HashMap的方式访问
}
Cat.sayHello();//调用对象的(方法)函数
2 new方式创建对象 有参数 或无参数
function Person(){ }
var personOne=new Person();//定义一个function,如果有new关键字去”实例化”,那么该function可以看作是一个类
personOne.name=”dylan”;
personOne.hobby=”coding”;
personOne.work=function(){
alert(personOne.name+” is coding now…”);
}
personOne.work();
3 使用工厂方式来创建(Object关键字)
var wcDog =new Object();
wcDog.name=”旺财”;
wcDog.age=3;
wcDog.work=function(){
alert(“我是”+wcDog.name+”,汪汪汪……”);
}
wcDog.work();
4 使用原型对象的方式 prototype关键字
function Dog(){}
Dog.prototype.name=”旺财”;
Dog.prototype.eat=function(){
alert(this.name+”是个吃货”);
}
var wangcai =new Dog();
wangcai.eat();
5 混合模式(原型和构造函数)
function Car(name,price){
this.name=name;
this.price=price;
}
Car.prototype.sell=function(){
alert(“我是”+this.name+”,我现在卖”+this.price+”万元”);
}
var camry =new Car(“凯美瑞”,27);
camry.sell();
6 动态原型的方式(可以看作是混合模式的一种特例)
function Car(name,price){
this.name=name;
this.price=price;
if(typeof Car.sell==”undefined”){
Car.prototype.sell=function(){
alert(“我是”+this.name+”,我现在卖”+this.price+”万元”);
}
Car.sell=true;
}
}
var camry =new Car(“凯美瑞”,27);
camry.sell();
#iframe的优缺点
优点:
1.iframe能够原封不动的把嵌入的网页展现出来。
2.如果有多个网页引用iframe,那么你只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷。
3.网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,可以增加代码的可重用。
4.如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决。
缺点:
1.会产生很多页面,不容易管理。
2.iframe框架结构有时会让人感到迷惑,如果框架个数多的话,可能会出现上下、左右滚动条,会分散访问者的注意力,用户体验度差。
3.代码复杂,无法被一些搜索引擎索引到,这一点很关键,现在的搜索引擎爬虫还不能很好的处理iframe中的内容,所以使用iframe会不利于搜索引擎优化。
4.很多的移动设备(PDA 手机)无法完全显示框架,设备兼容性差。
5.iframe框架页面会增加服务器的http请求,对于大型网站是不可取的。
分析了这么多,现在基本上都是用Ajax来代替iframe,所以iframe已经渐渐的退出了前端开发。
#js延迟加载的方式有哪些?
1 使用setTimeout延迟方法的加载时间
2 让js最后加载(放在body底部)
#哪些操作会造成内存泄漏? (比较重要)
内存泄露: 一块被分配的内存既不能使用,也不能回收。从而影响性能,甚至导致程序崩溃。
起因:JavaScript的垃圾自动回收机制会按一定的策略找出那些不再继续使用的变量,释放其占有的内存。
然而由于一些原因导致在这种机制下内存管理器不能正确解读JavaScript变量的生命周期,从而没有释放其内存,而也没有再被使用。
循环引用是导致以上情况的主要原因之一。
1 全局变量过多
:js中如果不用 var 声明变量,该变量将被视为 window 对象(全局对象)的属性,也就是全局变量.
1) function foo(arg) {
bar = “this is a hidden global variable”;
}
// 上面的函数等价于 你调用完了函数以后,变量仍然存在,导致泄漏.
function foo(arg) {
window.bar = “this is an explicit global variable”;
}
2) function foo() {
this.variable = “potential accidental global”;
}
// 没有对象调用foo, 也没有给它绑定this, 所以this是window
foo();
2 被遗忘的定时器或者回调
var someResource = getData();
setInterval(function() {
var node = document.getElementById(‘Node’);
if(node) {
node.innerHTML = JSON.stringify(someResource));
}
}, 1000);
这样的代码很常见, 如果 id 为 Node 的元素从 DOM 中移除, 该定时器仍会存在, 同时,
因为回调函数中包含对 someResource 的引用, 定时器外面的 someResource 也不会被释放
3 没有清理的DOM元素引用
var elements = {
button: document.getElementById(‘button’),
image: document.getElementById(‘image’),
text: document.getElementById(‘text’)
};
function doStuff() {
image.src = ‘http://some.url/image';
button.click();
console.log(text.innerHTML);
}
function removeButton() {
document.body.removeChild(document.getElementById(‘button’));
// 虽然我们用removeChild移除了button, 但是还在elements对象里保存着#button的引用
// 换言之, DOM元素还在内存里面.
}
4 闭包 不在使用后清空(闭包我发现其实有很多问题 不好理解 见老师 我会在问 你自己也去查一查 这个很重要)
#数组方法数组方法pop() push() unshift() shift()
push() 和 pop() 都是对末尾字符进行操作的
push()是尾部添加操作 pop()是尾部删除
push()返回的是length pop()返回的是删出的字符
unshift() 和 shift() 都是对首字符进行的操作
unshift()是头部添加 返回的是length
shift()首字符删除 返回值是删除的字符. Push()尾部添加 pop()尾部删除
Unshift()头部添加 shift()头部删除
#window.loction.search();返回的是什么?
window.location.search方法是截取当前url中“?”后面的字符串,
例如:index.php?act=doctor,截取后的字符串就是act=doctor
window.location 对象所包含的属性
属性 描述
hash 从井号 (#) 开始的 URL(锚)
host 主机名和当前 URL 的端口号
hostname 当前 URL 的主机名
href 完整的 URL
pathname 当前 URL 的路径部分
port 当前 URL 的端口号
protocol 当前 URL 的协议
search 从问号 (?) 开始的 URL(查询部分
#JavaScript中的垃圾回收机制
内存的生命周期
1 当需要的时候分配内存
2 对内存进行读写操作
3 当上面分配的内存不再需要的时候,将他们释放掉
过程:
1 变量初始化(自动分配相应的内存空间)
2 函数调用时候分配空间
3 操作变量值 读、写、函数调用
4 内存不再被使用时,将它们释放掉
5 垃圾回收
#精度问题:JS精度不能精确到0.1
console.log(0.1+0.2); //结果为 0.30000000000000004
原因:
其实对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,
只不过在 C++/C#/Java 这些语言中已经封装好了方法来避免精度的问题,
而 JavaScript 是一门弱类型的语言,从设计思想上就没有对浮点数有个严格的数据类型,
所以精度误差的问题就显得格外突出
计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制结果为:
0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)
双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串很长的二进制 0.0100110011001…
因浮点数小数位的限制而截断二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。
解决办法:给出明确的精度要求,在返回值的过程中,计算机会自动四舍五入
Math.formatFloat = function(f, digit) {
var m = Math.pow(10, digit);
return parseInt(f * m, 10) / m;
}
var numA = 0.1;
var numB = 0.2;
alert(Math.formatFloat(numA + numB, 1) === 0.3);
#BOM对象有哪些,列举window对象
BOM:
1. Window 对象:表示浏览器打开的窗口,包括获取焦点、改变滚动条、设置定时器等等。
2. Navigator 对象:包含浏览器信息。如:获取浏览器名称、版本信息、操作系统平台信息等等。
3. Screen 对象:包含屏幕信息。如:获取屏幕高度、宽度等等。
4. History 对象:可对当前页的浏览历史进行操作,如:前进、后退等。
5. Location 对象:可对当前页面的URL进行操作,如:导航到新的页面、获取URL信息等
window: (举例一些常用的就行..)
属性:
closed 返回窗口是否已被关闭。
defaultStatus 设置或返回窗口状态栏中的默认文本。
document 对 Document 对象的只读引用。请参阅 Document 对象。
history 对 History 对象的只读引用。请参数 History 对象。
innerheight 返回窗口的文档显示区的高度。
innerwidth 返回窗口的文档显示区的宽度。
length 设置或返回窗口中的框架数量。
location 用于窗口或框架的 Location 对象。请参阅 Location 对象。
name 设置或返回窗口的名称。
Navigator 对 Navigator 对象的只读引用。请参数 Navigator 对象。
opener 返回对创建此窗口的窗口的引用。
outerheight 返回窗口的外部高度。
outerwidth 返回窗口的外部宽度。
pageXOffset 设置或返回当前页面相对于窗口显示区左上角的 X 位置。
pageYOffset 设置或返回当前页面相对于窗口显示区左上角的 Y 位置。
parent 返回父窗口。
Screen 对 Screen 对象的只读引用。请参数 Screen 对象。
self 返回对当前窗口的引用。等价于 Window 属性。
status 设置窗口状态栏的文本。
top 返回最顶层的先辈窗口
方法:
alert() 显示带有一段消息和一个确认按钮的警告框。
blur() 把键盘焦点从顶层窗口移开。
clearInterval() 取消由 setInterval() 设置的 timeout。
clearTimeout() 取消由 setTimeout() 方法设置的 timeout。
close() 关闭浏览器窗口。
confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。
createPopup() 创建一个 pop-up 窗口。
focus() 把键盘焦点给予一个窗口。
moveBy() 可相对窗口的当前坐标把它移动指定的像素。
moveTo() 把窗口的左上角移动到一个指定的坐标。
open() 打开一个新的浏览器窗口或查找一个已命名的窗口。
print() 打印当前窗口的内容。
prompt() 显示可提示用户输入的对话框。
resizeBy() 按照指定的像素调整窗口的大小。
resizeTo() 把窗口的大小调整到指定的宽度和高度。
scrollBy() 按照指定的像素值来滚动内容。
scrollTo() 把内容滚动到指定的坐标。
setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。
setTimeout() 在指定的毫秒数后调用函数或计算表达式。
#js常用对象
window
document
location
History
Navigator
Screen
Array
Date
Math
RegExp
#怎样添加 移除 复制 创建和查找节点
创建新节点
createDocumentFragment() //创建一个DOM片段
createElement_x() //创建一个具体的元素
createTextNode() //创建一个文本节点
添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
如何优化你的代码
1代码重用
2避免全局变量(命名空间,封闭空间,模块化mvc..)
3拆分函数避免函数过于臃肿
#请说出三种减低页面加载时间的方法
1、压缩css、js文件
2、合并js、css文件,减少http请求
3、外部js、css文件放在最底下
4、尽量减少dom操作,尽可能用变量替代不必要的dom操作
#解释什么是sql注入,xss漏洞
SQL:当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击,如查询、插入数据时。
xss:通过插入恶意脚本,实现对用户浏览器的控制
#在JavaScript中什么是伪数组?如何将伪数组转化为标准数组
什么是伪数组:不能调用数组内置的一些属性和方法的数组(也就是假的 张的想而已)
例如:
这种对象有很多,比较特别的是arguments对象,还有像调用getElementsByTagName,document.childNodes之类的,
它们都返回NodeList对象都属于伪数组。
转化:
能通过Array.prototype.slice转换为真正的数组 带有length属性的对象。
我们可以通过Array.prototype.slice.call(fakeArray)将伪数组转变为真正的Array对象。
var fakeArray01 = {0:’a’,1:’b’,length:2};//这是一个标准的有伪数组对象
var arr01 = Array.prototype.slice.call(fakeArray01);
alert(arr01[0]);//a
var arr02 = [].slice.call(fakeArray01);
alert(arr02[0]);//a
#列举哪些方法对前端开发进行优化?
优化的目的:
1 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。
2 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
优化方法:
http请求过程:一个完整的请求都需要经过DNS寻址、与服务器建立连接、发送数据、等待服务器响应、接收数据这样一个“漫长”而复杂的过程
减少HTTP请求数
使用图片地图
使用CSS Sprites
合并JS和CSS文件
使用CDN(内容发布网络):当页面中有很多资源的时候,可以从不同的服务中去读取,同时可以提高并行下载速度
添加http Expires头:为图片视频之类很少改变的资源设置长的Expires时间将直接减少http请求
如果资源设置了Expires头为将来的某个时间,下次访问时候浏览器发现资源还没有过期,会直接从缓存中读取,不会 再次产生http请求
压缩组件:在Server端对Response资源进行压缩再传给浏览器,一般使用GZIP
将CSS放再顶部: 能加快页面内容显示,并且能避免页面产生白屏
将JS放在底部
JS会阻塞对其后面内容的呈现
JS会阻塞对其后面内容的下载
避免CSS表达式
将JS,CSS放在外部文件中
通过使用Keep-Alive和较少的域名来减少DNS查找
精简JS和CSS文件
寻找一种避免重定向的方法
移除重复的脚本
配置Etag
总结:优化这种东西 比较续 纯靠经验(自己在多去 看看 需要理解)
#请说出三种减低页面加载时间的方法
1、压缩css、js文件
2、合并js、css文件,减少http请求
3、外部js、css文件放在最底下
4、尽量减少dom操作,尽可能用变量替代不必要的dom操作
简述同步和异步的区别
javascript: 是单线程机制。所谓单线程就是按次序执行,执行完一个任务再执行下一个。
对于浏览器来说,也就是无法在渲染页面的同时执行代码。
单线程机制的优点在于实现起来较为简单,运行环境相对简单。
缺点在于,如果中间有任务需要响应时间过长,经常会导致
页面加载错误或者浏览器无响应的状况。这就是所谓的“同步模式”,程序执行顺序与任务排列顺序一致。对于浏览器来说,
同步模式效率较低,耗时长的任务都应该使用异步模式;而在服务器端,异步模式则是唯一的模式,如果采用同步模式个人认为
服务器很快就会出现12306在高峰期的表现。。。。
同步: 阻塞模式 就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,
那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步: 非阻塞模式 是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。
当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
例如;
1)回调函数callback
所谓回调函数,就是将函数作为参数传到需要回调的函数内部再执行。
典型的例子就是发送ajax请求。例如:
$.ajax({
async: false,
cache: false,
dataType: ‘json’,
url: “url”,
success: function(data) {
console.log(‘success’);
},
error: function(data) {
console.log(‘error’);
}
})
当发送ajax请求后,等待回应的过程不会堵塞程序运行,耗时的操作相当于延后执行。
回调函数的优点在于简单,容易理解,但是可读性较差,耦合度较高,不易于维护。
解释jsonp的原理,以及为什么不是真正的ajax
Ajax是页面无刷新请求数据操作
动态创建script标签,回调函数
1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加标签具有可跨域的特性,由服务端返回一个预先定义好的jabascript函数的调用,
并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合才能完成。
备注:
1 | 前端的路上我们一起携手共进!如果转载,请标注本链接地址。 |
Email:58267980@qq.com
最后更新: 2019年01月24日 13:09
