javascript常见的20个问题与解决⽅法
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>javascript常见的20个问题与解决⽅法</title>
</head>
<body>
<h1>javascript常见的20个问题与解决⽅法</h1>
<p><br />
<strong>1、offsetWidth/offsetHeight,clientWidth/clientHeight与scrollWidth/scrollHeight的区别</strong><br />
1)offsetWidth/offsetHeight返回值包含content+padding+border,效果与e.getBoundingClientRect()相同<br />
2)clientWidth/clientHeight返回值只包含content+padding,如果有滚动条,也不包含滚动条<br />
3)scrollWidth/scrollHeight返回值包含content+padding+溢出内容的尺⼨</p>
<p><strong>2、XMLHttpRequest通⽤属性和⽅法</strong><br />
1)readyState:表⽰请求状态的整数,取值:<br />
UNSENT(0):对象已创建<br />
OPENED(1):open()成功调⽤,在这个状态下,可以为xhr设置请求头,或者使⽤send()发送请求<br />
HEADERS_RECEIVED(2):所有重定向已经⾃动完成访问,并且最终响应的http头已经收到<br />
LOADING(3):响应体正在接收<br />
DONE(4):数据传输完成或者传输产⽣错误<br />
2)onreadystatechange:readyState改变时调⽤的函数<br />
3)status:服务器返回的http状态码(如:200,404)<br />
4)statusText:服务器返回的http状态信息(如:ok,no content)<br />
5)responseText:作为字符串形式的来⾃服务器的完整响应<br />
6)responseXML:Document对象,表⽰服务器的响应解析成的XML⽂档<br />
7)abort():取消异步http请求<br />
8)getAllResponseHeaders():返回⼀个字符串,包含响应中服务器发送的全部http报头。每个报头都是⼀个⽤冒号分隔开的名/值对,并且使⽤⼀个回车/换⾏来分隔报头⾏<br />
9)getResponseHeader(headerName):返回headName对应的报头值<br />
10)open(method,url,asynchronous [,user,password]):初始化准备发送到服务器上的请求<br />
method:http⽅法,不区分⼤⼩写<br />
url:请求发送的相对或绝对url<br />
asynchronous:表⽰请求是否异步<br />
user和password:提供⾝份验证<br />
11)setRequestHeader(name,value):设置http报头<br />
12)send(body):对服务器请求进⾏初始化。参数body包含请求的主体部分,对于post请求为键值对字符串;对于get请求,为null</p>
<p><strong>3、focus/blur与focusin/focusout的区别与联系</strong><br />
1)focus/blur不冒泡,focusin/focusout冒泡<br />
2)focus/blur兼容性好,focusin/focusout在除FireFox外的浏览器下都保持良好兼容性,如需使⽤事件托管,可考虑在FireFox下使⽤事件捕获elem.addEventListener('focus',handler,true)<br />
3)可获得焦点的元素:<br />
i.window<br />
ii.链接被点击或键盘操作<br />
iii.表单空间被点击或键盘操作<br />
iv.设置tabindex属性的元素被点击或键盘操作</p>
<p><strong>4、mouseover/mouseout与mouseenter/mouseleave的区别与联系</strong><br />
1)mouseover/mouseout是标准事件,所有浏览器都⽀持;mouseenter/mouseleave是IE5.5引⼊的特有事件,后来被DOM3标准采纳,现代标准浏览器也⽀持<br />
2)mouseover/mouseout是冒泡事件;mouseenter/mouseleave不冒泡。需要为多个元素监听⿏标移⼊/出事件时,推荐mouseover/mouseout托管,提⾼性能<br />
3)标准事件模型中event.target表⽰发⽣移⼊/出的元素,latedTarget对应移出/⼊元素;在⽼IE中event.srcElement表⽰发⽣移⼊/出的元素,Element表⽰移出的⽬标元素,event.fromElement表⽰移⼊时的来源元素<br
例⼦:⿏标从div#target元素移出时进⾏处理,判断逻辑如下:<br />
<div id="target"><span>test</span></div></p>
<p><script type="text/javascript"><br />
var target = ElementById('target');<br />
if (target.addEventListener) {<br />
target.addEventListener('mouseout', mouseoutHandler, false);<br />
} else if (target.attachEvent) {<br />
target.attachEvent('onmouseout', mouseoutHandler);<br />
}</p>
<p>function mouseoutHandler(e) {<br />
e = e || window.event;<br />
var target = e.target || e.srcElement;</p>
<p> // 判断移出⿏标的元素是否为⽬标元素<br />
if (target.id !== 'target') {<br />
return;<br />
}</p>
<p> // 判断⿏标是移出元素还是移到⼦元素<br />
var relatedTarget = latedTarget || e.toElement;<br />
while (relatedTarget !== target<br />
&& UpperCase() !== 'BODY') {<br />
relatedTarget = relatedTarget.parentNode;<br />
}</p>
<p> // 如果相等,说明⿏标在元素内部移动<br />
if (relatedTarget === target) {<br />
return;<br />
}</p>
<p> // 执⾏需要操作<br />
//alert('⿏标移出');</p>
<p>}<br />
</script></p>
<p> </p>
<p><strong>5、sessionStorage,localStorage,cookie区别</strong><br />
1)都会在浏览器端保存,有⼤⼩限制,同源限制<br />
2)cookie会在请求时发送到服务器,作为会话标识,服务器可修改cookie;web storage不会发送到服务器<br />
3)cookie有path概念,⼦路径可以访问⽗路径cookie,⽗路径不能访问⼦路径cookie<br />
4)有效期:cookie在设置的有效期内有效,默认为浏览器关闭;sessionStorage在窗⼝关闭前有效,localStorage长期有效,直到⽤户删除<br />
5)共享:sessionStorage不能共享,localStorage在同源⽂档之间共享,cookie在同源且符合path规则的⽂档之间共享<br />
6)localStorage的修改会触发其他⽂档窗⼝的update事件<br />
7)cookie有secure属性,要求https传输<br />
8)浏览器不能保存超过300个cookie,单个服务器不能超过20个,每个cookie不能超过4k。web storage⼤⼩⽀持能达到5M</p>
<p><strong>6、javascript跨域通信</strong><br />
同源:两个⽂档同源需满⾜<br />
1)协议相同<br />
js控制滚动条2)域名相同<br />
3)端⼝相同<br />
跨域通信:js进⾏DOM操作、通信时如果⽬标与当前窗⼝不满⾜同源条件,浏览器为了安全会阻⽌跨域操作。<br />
跨域通信通常有以下⽅法:<br />
1)如果是log之类的简单单项通信,新建<img>,<script>,<link>,<iframe>;元素,通过src,href属性设置为⽬标url,实现跨域请求<br />
2)如果请求json数据,使⽤<script>;进⾏jsonp请求<br />
3)现代浏览器中多窗⼝通信使⽤html5规范的targetWindow.postMessage(data,origin);其中data是需要发送的对象,origin是⽬标窗⼝的origin。window.addEventListener('message',handler,false);handler的event.data是postMessage发送来的数据,e 4)内部服务器代理请求跨域url,然后返回数据<br />
5)跨域请求数据,现代浏览器可使⽤html5规范的cors功能,只要⽬标服务器返回http头部Access-Control-Allow-Origin:*即可像普通ajax⼀样访问跨域资源</p>
<p><strong>7、javascript有哪⼏种数据类型?</strong><br />
六种基本数据类型:<br />
undefined<br />
null<br />
string<br />
boolean<br />
number<br />
symbol<br />
⼀种引⽤类型<br />
Object</p>
<p><strong>8、什么是闭包?闭包有什么⽤?</strong><br />
闭包是在某个作⽤域内定义的函数,它可以访问这个作⽤域内的所有变量。<br />
闭包作⽤域链通常包括三个部分:<br />
1)函数本⾝作⽤域<br />
2)闭包定义时的作⽤域<br />
3)全局作⽤域<br />
闭包常见⽤途:<br />
1)创建特权⽅法⽤于访问控制<br />
2)事件处理程序及回调</p>
<p>9、javascript有哪⼏种⽅法定义函数?<br />
1)函数声明表达式<br />
2)function操作符<br />
3)Function构造函数<br />
4)ES6:arrow function</p>
<p><strong>10、应⽤程序存储和离线web应⽤</strong><br />
html5新增应⽤程序缓存,允许web应⽤将应⽤程序⾃⾝保存到⽤户浏览器中,⽤户离线状态也能访问。<br />
1)为html元素设置manifest属性:<html manifest="myapp.appcache">,其中后缀名只是⼀个约定,真正识别⽅式是通过text/cache-manifest作为MIME类型。所以需要配置服务器保证设置正确<br />
2)manifest⽂件⾸⾏为CACHE MANIFEST,其余就是要缓存的URL列表,每个⼀⾏,相对路径都相对于manifest⽂件的url。注释以#开头<br />
3)url分为三种类型:CACHE为默认类型,NETWORK表⽰资源从不缓存,FALLBACK每⾏包含两个url,第⼆个url是指需要加载和存储在缓存中的资源,第⼀个url是⼀个前缀。任何匹配该前缀的url都不会缓存,如果从⽹络中载⼊这样的url失败的话CACHE MANIFEST</p>
<p>CACHE:<br />
myapp.html<br />
myapp.css<br />
myapp.js</p>
<p>FALLBACK:<br />
videos/ offline_help.html</p>
<p>NETWORK:<br />
cgi/</p>
<p> </p>
<p><strong>11、客户端存储localStorage和sessionStorage</strong><br />
1)localStorage有效期为永久,sessionStorage有效期为顶层窗⼝关闭前<br />
2)同源⽂档可以读取并修改localStorage数据,sessionStorage只允许同⼀个窗⼝下的⽂档访问,如通过iframe引⼊的同源⽂档<br />
3)Storage对象通常被当做普通js对象使⽤:通过设置属性来存取字符串值,也可以通过setItem(key,value)设置,getItem(key)读取,removeItem(key)删除,clear()删除所有数据,length表⽰已存储的数据项数⽬,key(index)返回对应索引的key
localStorage.setItem('x', 1); // storge x->1<br />
<p>// 枚举所有存储的键值对<br />
for (var i = 0, len = localStorage.length; i < len; ++i ) {<br />
var name = localStorage.key(i);<br />
var value = Item(name);<br />
}</p>
<p&veItem('x'); // remove x<br />
localStorage.clear(); // remove all data</p>
<p> </p>
<p><strong>12、cookie及其操作</strong><br />
1)cookie是web浏览器存储的少量数据,最早设计为服务器端使⽤,作为HTTP协议的扩展实现。cookie数据会⾃动在浏览器和服务器之间传输。<br />
2)通过读写cookie检测是否⽀持<br />
3)cookie属性有名,值,max-age,path, domain,secure;<br />
4)cookie默认有效期为浏览器会话,⼀旦⽤户关闭浏览器,数据就丢失,通过设置max-age=seconds属性告诉浏览器cookie有效期<br />
5)cookie作⽤域通过⽂档源和⽂档路径来确定,通过path和domain进⾏配置,web页⾯同⽬录或⼦⽬录⽂档都可访问<br />
6)通过cookie保存数据的⽅法为:为kie设置⼀个符合⽬标的字符串如下<br />
7)读取kie获得'; '分隔的字符串,key=value,解析得到结果<br />
<p&kie = 'name=aaa; path=/; domain=domain; secure';<br />
// 要改变cookie的值,需要使⽤相同的名字、路径和域,新的值<br />
// 来设置cookie,同样的⽅法可以⽤来改变有效期</p>
<p>// 设置max-age为0可以删除指定cookie</p>
<p>//读取cookie,访问kie返回键值对组成的字符串,<br />
//不同键值对之间⽤'; '分隔。通过解析获得需要的值</p>
<p> </p>
<p><strong>13、javascript有哪些⽅法定义对象?</strong><br />
1)对象字⾯量:var obj = {};<br />
2)构造函数:var obj = new Object();<br />
3)ate():var obj = ate(Object.prototype);</p>
<p><strong>14、===运算符判断相等的流程是怎样的?</strong><br />
1)如果两个值不是相同类型,它们不相等<br />
2)如果两个值都是null或者都是undefined,它们相等<br />
3)如果两个值都是布尔类型true或者都是false,它们相等<br />
4)如果其中有⼀个是NaN,它们不相等<br />
5)如果都是数值型并且数值相等,它们相等,-0等于0<br />
6)如果它们都是字符串并且在相同位置包含相同的16位值,它们相等;如果在长度或者内容上不等,它们不相等;两个字符串显⽰结果相同但是编码不同,==和===都认为它们不相等<br />
7)如果它们指向相同对象、数组、函数,它们相等;如果指向不同对象,它们不相等</p>
<p><strong>15、==运算符判断相等的流程是怎样的?</strong><br />
1)如果两个值类型相同,按照===⽐较⽅法进⾏⽐较<br />
2)如果类型不同,使⽤如下规则进⾏⽐较<br />
i.如果其中⼀个值是null,另⼀个是undefined,它们相等<br />
ii.如果⼀个值是数字另⼀个是字符串,将字符串转换为数字进⾏⽐较<br />
iii.如果有布尔类型,将true转换为1,false转换为0,然后⽤==规则继续⽐较<br />
iv.如果⼀个值是对象,另⼀个是数字或字符串,将对象转换为原始值然后⽤==规则继续⽐较<br />
v.其他所有情况都认为不相等</p>
<p><strong>16、对象到字符串的转换步骤</strong><br />
1)如果对象有toString()⽅法,js调⽤它。如果返回⼀个原始值(primitive value如:string,number,boolean),将这个值转换为字符串作为结果<br />
2)如果对象没有toString()⽅法或者返回值不是原始值,js寻对象的valueOf()⽅法,如果存在就调⽤它,返回结果是原始值则转为字符串作为结果<br />
3)否则,js不能从toString()或者valueOf()获得⼀个原始值,此时throws a TypeError<br />
<br />
<strong>17、对象到数字的转换步骤</strong><br />
1)如果对象有valueOf()⽅法并且返回元素值,js将返回值转换为数字作为结果<br />
2)否则,如果对象有toString()并且返回原始值,js将返回结果转换为数字作为结果<br />
3)否则,throws a TypeError</p>
<p><strong>18、+运算符⼯作流程</strong><br />
1)如果有操作数是对象,转换为原始值<br />
2)此时如果有⼀个操作数是字符串,其他的操作数都转换为字符串并执⾏连接<br />
3)否则,所有操作数都转换为数字并执⾏家法</p>
<p><strong>19、函数内部arguments变量有哪些特性,有哪些属性,如何将它转换为数组?</strong><br />
1)arguments所有函数中都包含的⼀个局部变量,是⼀个类数组对象,对应函数调⽤时的实参。如果函数定义同名参数会在调⽤时覆盖默认对象<br />
2)arguments[index]分别对应函数调⽤时的实参,并且通过arguments修改实参时会同时修改实参<br />
3)arguments.length为实参的个数(Function.length表⽰形参长度)<br />
4)arguments.callee为当前正在执⾏的函数本⾝,使⽤这个属性进⾏递归调⽤时需注意this的变化<br />
5)arguments.caller为调⽤当前函数的函数(已被遗弃)<br />
6)转换为数组:var args = Array.prototype.slice.call(arguments, 0);</p>
<p><strong>20、评价⼀下三种⽅法实现继承的优缺点,并改进</strong><br />
function Shape() {}</p>
<p>function Rect() {}</p>
<p>// ⽅法1<br />
Rect.prototype = new Shape();</p>
<p>// ⽅法2<br />
Rect.prototype = Shape.prototype;</p>
<p>// ⽅法3<br />
Rect.prototype = ate(Shape.prototype);</p>
<p>Rect.prototype.area = function () {<br />
// do something<br />
};<br />
</p>
<p>⽅法1:<br />
1)优点:正确设置原型链实现继承<br />
2)优点:⽗类实例属性得到继承,原型链查效率提⾼,也能为⼀些属性提供合理的默认值<br />
3)缺点:⽗类实例属性为引⽤类型时,不恰当地修改会导致所有⼦类被修改<br />
4)缺点:创建⽗类实例作为⼦类原型时,可能⽆法确定构造函数需要的合理参数,这样提供的参数继承给⼦类没有实际意义,当⼦类需要这些参数时应该在构造函数中进⾏初始化和设置<br />
5)总结:继承应该是继承⽅法⽽不是属性,为⼦类设置⽗类实例属性应该是通过在⼦类构造函数中调⽤⽗类构造函数进⾏初始化<br />
⽅法2:<br />
1)优点:正确设置原型链实现继承<br />
2)缺点:⽗类构造函数原型与⼦类相同。修改⼦类原型添加⽅法会修改⽗类<br />
⽅法3:<br />
1)优点:正确设置原型链且避免⽅法1.2中的缺点<br />
2)缺点:ES5⽅法需要注意兼容性<br />
改进:<br />
1)所有三种⽅法应该在⼦类构造函数中调⽤⽗类构造函数实现实例属性初始化<br />
function Rect() {<br />
Shape.call(this);<br />
}<br />
</p>
<p>2)⽤新创建的对象替代⼦类默认原型,设置structor = Rect;保证⼀致性<br />
3)第三种⽅法的polyfill:<br />
function create(obj) {<br />
if (ate) {<br />
ate(obj);<br />
}</p>
<p> function f() {};<br />
f.prototype = obj;<br />
return new f();<br />
}<br />
</p>
</body>
</html>
javascript常见的20个问题与解决⽅法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论