前端面试题及答案(七)

请解释一下 JavaScript 的同源策略。
概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。 指一段脚本只能读取来自同一来源的窗口和文档的属性。
为什么要有同源限制?
我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。
什么是 "use strict"; ? 使用它的好处和坏处分别是什么?
ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。
设立"严格模式"的目的,主要有以下几个:
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
注:经过测试IE6,7,8,9均不支持严格模式。
缺点: 现在网站的JS 都会进行压缩,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge 后,这个串就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节。
GET和POST的区别,何时使用POST?
   GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符
   POST:一般用于修改服务器上的资源,对所发送的信息没有限制。

   GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,
   也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。

然而,在以下情况中,请使用 POST 请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
哪些地方会出现css阻塞,哪些地方会出现js阻塞?
js的阻塞特性:所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。直到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。为了提高用户体验,新一代浏览器都支持并行下载JS,但是JS下载仍然会阻塞其它资源的下载(例如.图片,css文件等)。
由于浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现。
嵌入JS会阻塞所有内容的呈现,而外部JS只会阻塞其后内容的显示,2种方式都会阻塞其后资源的下载。也就是说外部样式不会阻塞外部脚本的加载,但会阻塞外部脚本的执行。
CSS怎么会阻塞加载了?CSS本来是可以并行下载的,在什么情况下会出现阻塞加载了(在测试观察中,IE6下CSS都是阻塞加载)
当CSS后面跟着嵌入的JS的时候,该CSS就会出现阻塞后面资源下载的情况。而当把嵌入JS放到CSS前面,就不会出现阻塞的情况了。
根本原因:因为浏览器会维持html中css和js的顺序,样式表必须在嵌入的JS执行前先加载、解析完。而嵌入的JS会阻塞后面的资源加载,所以就会出现上面CSS阻塞下载的情况。
嵌入JS应该放在什么位置?
  1、放在底部,虽然放在底部照样会阻塞所有呈现,但不会阻塞资源下载。

  2、如果嵌入JS放在head中,请把嵌入JS放在CSS头部。

  3、使用defer(只支持IE)

  4、不要在嵌入的JS中调用运行时间较长的函数,如果一定要用,可以用`setTimeout`来调用
Javascript无阻塞加载具体方式
将脚本放在底部。<link>还是放在head中,用以保证在js加载前,能加载出正常显示的页面。<script>标签放在</body>前。
成组脚本:由于每个<script>标签下载时阻塞页面解析过程,所以限制页面的<script>总数也可以改善性能。适用于内联脚本和外部脚本。
非阻塞脚本:等页面完成加载后,再加载js代码。也就是,在window.onload事件发出后开始下载代码。 (1)defer属性:支持IE4和fierfox3.5更高版本浏览器 (2)动态脚本元素:文档对象模型(DOM)允许你使用js动态创建HTML的几乎全部文档内容。代码如下:

<script>
var script=document.createElement("script");
script.type="text/javascript";
script.src="file.js";
document.getElementsByTagName("head")[0].appendChild(script);
</script>
此技术的重点在于:无论在何处启动下载,文件额下载和运行都不会阻塞其他页面处理过程。即使在head里(除了用于下载文件的http链接)。
闭包相关问题?
详情请见:详解js闭包
js事件处理程序问题?
详情请见:JavaScript学习总结(九)事件详解
eval是做什么的?
它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
JavaScript原型,原型链 ? 有什么特点?
*  原型对象也是普通的对象,是对象一个自带隐式的 __proto__ 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链。
*  原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链。
事件、IE与火狐的事件机制有什么区别? 如何阻止冒泡?
1. 我们在网页中的某个操作(有的操作对应多个事件)。例如:当我们点击一个按钮就会产生一个事件。是可以被 JavaScript 侦测到的行为。  
2. 事件处理机制:IE是事件冒泡、firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件。;
3.  ev.stopPropagation();注意旧ie的方法 ev.cancelBubble = true;


ajax 是什么?ajax 的交互模型?同步和异步的区别?如何解决跨域问题?
详情请见:JavaScript学习总结(七)Ajax和Http状态字
1. 通过异步模式,提升了用户体验

 2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用

 3. Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载。

 2. Ajax的最大的特点是什么。

 Ajax可以实现动态不刷新(局部刷新)
 readyState属性 状态 有5个可取值: 0=未初始化 ,1=启动 2=发送,3=接收,4=完成

ajax的缺点

 1、ajax不支持浏览器back按钮。

 2、安全问题 AJAX暴露了与服务器交互的细节。

 3、对搜索引擎的支持比较弱。

 4、破坏了程序的异常机制。

 5、不容易调试。

跨域: jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面
js对象的深度克隆
 function clone(Obj) {  
       var buf;  
       if (Obj instanceof Array) {  
           buf = [];  //创建一个空的数组
           var i = Obj.length;  
           while (i--) {  
               buf[i] = clone(Obj[i]);  
           }  
           return buf;  
       }else if (Obj instanceof Object){  
           buf = {};  //创建一个空对象
           for (var k in Obj) {  //为这个对象添加新的属性
               buf[k] = clone(Obj[k]);  
           }  
           return buf;  
       }else{  
           return Obj;  
       }  
   }  
AMD和CMD 规范的区别?
详情请见:详解JavaScript模块化开发
网站重构的理解?
网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。

对于传统的网站来说重构通常是:

表格(table)布局改为DIV+CSS
使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)
对于移动平台的优化
针对于SEO进行优化
深层次的网站重构应该考虑的方面

减少代码间的耦合
让代码保持弹性
严格按规范编写代码
设计可扩展的API
代替旧有的框架、语言(如VB)
增强用户体验
通常来说对于速度的优化也包含在重构中

压缩JS、CSS、image等前端资源(通常是由服务器来解决)
程序的性能优化(如数据读写)
采用CDN来加速资源加载
对于JS DOM的优化
HTTP服务器的文件缓存
如何获取UA?
<script>
   function whatBrowser() {  
       document.Browser.Name.value=navigator.appName;  
       document.Browser.Version.value=navigator.appVersion;  
       document.Browser.Code.value=navigator.appCodeName;  
       document.Browser.Agent.value=navigator.userAgent;  
   }  
</script>
js数组去重
以下是数组去重的三种方法:
Array.prototype.unique1 = function () {
 var n = []; //一个新的临时数组
 for (var i = 0; i < this.length; i++) //遍历当前数组
 {
   //如果当前数组的第i已经保存进了临时数组,那么跳过,
   //否则把当前项push到临时数组里面
   if (n.indexOf(this[i]) == -1) n.push(this[i]);
 }
 return n;
}

Array.prototype.unique2 = function()
{
   var n = {},r=[]; //n为hash表,r为临时数组
   for(var i = 0; i < this.length; i++) //遍历当前数组
   {
       if (!n[this[i]]) //如果hash表中没有当前项
       {
           n[this[i]] = true; //存入hash表
           r.push(this[i]); //把当前数组的当前项push到临时数组里面
       }
   }
   return r;
}

Array.prototype.unique3 = function()
{
   var n = [this[0]]; //结果数组
   for(var i = 1; i < this.length; i++) //从第二项开始遍历
   {
       //如果当前数组的第i项在当前数组中第一次出现的位置不是i,
       //那么表示第i项是重复的,忽略掉。否则存入结果数组
       if (this.indexOf(this[i]) == i) n.push(this[i]);
   }
   return n;
}
HTTP状态码
100  Continue  继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
200  OK   正常返回信息
201  Created  请求成功并且服务器创建了新的资源
202  Accepted  服务器已接受请求,但尚未处理
301  Moved Permanently  请求的网页已永久移动到新位置。
302 Found  临时性重定向。
303 See Other  临时性重定向,且总是使用 GET 请求新的 URI。
304  Not Modified  自从上次请求后,请求的网页未修改过。

400 Bad Request  服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
401 Unauthorized  请求未授权。
403 Forbidden  禁止访问。
404 Not Found  找不到如何与 URI 相匹配的资源。

500 Internal Server Error  最常见的服务器端错误。
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。
js操作获取和设置cookie
//创建cookie
function setCookie(name, value, expires, path, domain, secure) {
   var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
   if (expires instanceof Date) {
       cookieText += '; expires=' + expires;
   }
   if (path) {
       cookieText += '; expires=' + expires;
   }
   if (domain) {
       cookieText += '; domain=' + domain;
   }
   if (secure) {
       cookieText += '; secure';
   }
   document.cookie = cookieText;
}

//获取cookie
function getCookie(name) {
   var cookieName = encodeURIComponent(name) + '=';
   var cookieStart = document.cookie.indexOf(cookieName);
   var cookieValue = null;
   if (cookieStart > -1) {
       var cookieEnd = document.cookie.indexOf(';', cookieStart);
       if (cookieEnd == -1) {
           cookieEnd = document.cookie.length;
       }
       cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
   }
   return cookieValue;
}

//删除cookie
function unsetCookie(name) {
   document.cookie = name + "= ; expires=" + new Date(0);
}
说说TCP传输的三次握手策略
为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送  后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了TCP的标志:SYN和ACK。
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
说说你对Promise的理解
依照 Promise/A+ 的定义,Promise 有四种状态:
pending: 初始状态, 非 fulfilled 或 rejected.
fulfilled: 成功的操作.
rejected: 失败的操作.
settled: Promise已被fulfilled或rejected,且不是pending
另外, fulfilled 与 rejected 一起合称 settled。
Promise 对象用来进行延迟(deferred) 和异步(asynchronous ) 计算。
Promise 的构造函数
构造一个 Promise,最基本的用法如下:
var promise = new Promise(function(resolve, reject) {
   if (...) {  // succeed
       resolve(result);
   } else {   // fails
       reject(Error(errMessage));
   }
});
Promise 实例拥有 then 方法(具有 then 方法的对象,通常被称为 thenable)。它的使用方法如下:
promise.then(onFulfilled, onRejected)
接收两个函数作为参数,一个在 fulfilled 的时候被调用,一个在 rejected 的时候被调用,接收参数就是 future,onFulfilled 对应 resolve, onRejected 对应 reject。

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):