(1)JavaScript包括哪些数据类型?
1.未定义(undefined) 2.空(null) 3.布尔(boolean) 4.字符串(string)
5.数字(number) 6.对象(object)
7.引用(reference) 8.列表(list) 9.完成(completion)
reference,list,completion这3种类型是作为JavaScript运行时中间结果的数据类型 在代码中不能使用。javascript
(2)border-color-left、marin-left、-moz-viewport改写成JavaScript
borderColorLeft,marinLeft, MozViewport,
-moz-border-radius确实是写成MozBorderRadius.css
(3)请简述javascript延迟加载的方式?
(1)将js脚本放在</body>以前,这样就能够在页面都显示以后,在继续加载.
(2)使用script标签的defer和async属性,defer属性为延迟加载,是在页面渲染完成以后再进行加载的,html
而async属性则是和文档并行加载,这两种解决方案都不完美,缘由在于不是全部浏览器都支持.async(异步).
(3)监听onload事件,动态加载.前端
var script = document.createElement ("script"); script.type = "text/javascript"; //Firefox, Opera, Chrome, Safari 3+ script.onload = function(){ alert("Script loaded!");}; //Internet Explorer script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; alert("Script loaded."); } }; script.src = "script.js"; document.getElementsByTagName("head")[0].appendChild(script);
(4)经过ajax下载js脚本,动态添加script节点.
这种方式与第二种相似,区别就在与js脚本的自动下载仍是经过ajax下载,ajax的方式显然可控制性更好一点,它能够先下载js文件,但不当即执行:java
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); xhr.open("get", "script.js", true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { var script = document.createElement ("script"); script.type = "text/javascript"; script.text = xhr.responseText; document.body.appendChild(script); } } }; xhr.send(null);
(5)使用js函数setTimeout()延迟执行node
<script language="JavaScript" src="" id="my"></script> <script> //延时3秒 setTimeout(function () { document.getElementById('my').src='script.css'; },3000); </script>
(5)看x, y, z的结果? //1 4 4jquery
<script type="text/javascript"> var x=1,y=z=0; function add(n) { alert(‘one’); return n=n+1; } y=add(x);
//y = 4,执行这段代码的时候,函数已经被替换了 alert( " y = " + y);
//这个函数被重定义了.代替了以前的函数. function add(n) { alert(‘two); return n=n+3; }
z=add(x); alert(x + " " + y + " " + z ); //1 4 4
</script>
两次执行的都是弹出two.证实执行的都是第二个声明函数,
证实函数执行以前,就已经完成替换了. 因为js是一个弱类型语言,不存在函数重载。重名函数就覆盖替换。ajax
由于没法判读int 或者是多参数问题。因此函数只能用名字判断。做为惟一标识。express
变量的定义是在全部代码执行的以前,在一个做用域内最早被预留在内存中的,这个变量占用了内存的存储位置,但尚未被定义(undefined),apache
只有在遇到定义变量的语句的时候,才被赋值(defined)。程序的执行在变量存储以后按顺序进行的,在执行第一句alert的时候,变量没有被赋值,因此弹出undefined。
(6)试从域名解析原理的角度简单分析,域名劫持是怎么发生的?有什么危害?
域名就是DNS,用户IP记不住就记域名,www.baidu.com就是一个域名.电脑会把域名翻译成IP地址..
域名的结构:是树形,分割是点 . 好比 以网易的域名为例:
3g.163.com 的上级域名是 .163.com
163.com 的上级域名是 .com
这里的 .com 就被称为顶级域名(Top-Level Domain,简称 TLD)
解析原理:当你在浏览器的地址栏中输入 www.163.com,而后敲回车,这时候电脑软件会进行以下一系列事情。
1. 首先根据输入的网址,提取出域名。
2. 若是你在系统中配置了 Hosts 文件,那么电脑会先查询 Hosts 文件,看这个www.163.com 否已经在 Hosts 里面有了对应的记录。若是有,直接就能够拿到该记录中的 IP地址,过程就结束了。
3. 若是 Hosts 里面没有这个别名,那么电脑会看你有没有设置域名服务器(DNS 服务器)。若是你的系统没有设置域名服务器,那电脑就没辙了,浏览器直接会报错,说网站的域名没法解析。过程就结束了。
4. 若是你设置过“域名服务器”,那么电脑会向这个域名服务器发送一个域名查询(DNS query)的请求,而后等候域名服务器的回应。
5. 若是域名服务器始终没有回应(好比域名服务器挂了,或域名服务器的IP填错了,或请求被拦截了),那么电脑仍是没辙(浏览器会报错)。
6. 若是域名服务器回应了,那么你的电脑就能够根据域名服务器的应答信息,获得该域名的 IP地址。以后浏览器就会向这个 IP地址 对应的 Web 端口发送 HTTP 请求。
一般状况下,电脑拿到的(DNS服务器)应答信息是正确的——也就是说,应答中的IP地址确实对应那个域名——这种状况下,你的网络软件就能够正常工做了。
域名服务器上都会保存一大堆的域名记录(每条记录包含“域名”和“IP地址”)。当收到域名查询的时候,域名服务器会从这堆记录中找到对方想要的,而后回应给对方。若是域名服务器上的某条记录被【人为修改】了(改为错的),那么一旦要查询这条记录,获得的就是错误的结果。这种状况称之为“域名劫持”。“域名劫持”的根源在于:域名服务器上的记录被人给改了。最直接的办法就是不要使用这种流氓 ”一般是电信运营商(ISP)提供的域名服务器,改用国外那些比较靠谱的。目前口碑最好的,大概是 Google提供的两个域名服务器,IP地址分别是 8.8.8.8 和 8.8.4.4 ——这俩不光是地址好记,更重要的是,不会耍流氓。
域名劫持的危害:好比,把维基百科的流量重定向到XX,篡改本身的域名服务器的记录,把里面跟维基百科相关的域名记录的 IP地址修改成XX的 IP地址。如此一来,假设你用的是这个 ISP 的域名服务器,当你在浏览器输入 http://zh.wikipedia.org/的时候,你的电脑查询到的 IP地址 实际上是XX的 IP地址,因此浏览器打开的是“XX”的主页。域名劫持实际上就是把网站重定向了。你想去A,结果成了B。
“域名污染”的原理,简单说来是这样滴:当你的电脑向域名服务器发送了“域名查询”的请求,而后域名服务器把回应发送给你的电脑,这之间是有一个时间差的。若是某个攻击者可以在域名服务器的“DNS应答”尚未到达你的电脑以前,先伪造一个错误的“DNS应答”发给你电脑。那么你的电脑收到的就是错误的信息,并获得一个错误的 IP地址。“域名污染”也叫“域名缓存投毒”。
(7)列举至少5种前端性能优化的具体方法,简要说明理由。
A:尽可能减小HTTP请求。
前端优化的黄金准则指导着前端页面的优化策略:只有10%-20%的最终用户响应时间花在接受请求的HTML文档上,剩下的80%-90%时间花在为HTML文档所引用的全部组件(图片、脚本、样式表等)进行的HTTP请求上。所以,改善响应时间的最简单途径就是减小组件的数量,并由此减小HTTP请求的数量。
① 图片地图:容许在一张图片上关联多个URL,而目标URL的选择取决于用户单击了图片上的哪一个位置。这样多个图片合并成一张图片,这样图片的HTTP请求就减小了。(不过图片地图只支持矩形形状,其余形状不支持。)
② CSS Sprites(图像精灵):将多个图片合并到一张单独的图片,这样就大大减小了页面中图片的HTTP请求。(对于当前网络流行的速度而言,不高于200KB的单张图片的所需载入时间基本是差很少的。)
③ 内联图片和脚本使用data:URL(Base64编码)模式直接将图片包含在Web页面中而无需进行HTTP请求。可是此种方法存在明显缺陷:- 不受IE的欢迎;- 图片太大不宜采用这种方式,由于Base64编码以后会增长图片大小,这样页面总体的下载量会变大;- 内联图片在页面跳转的时候不会被缓存。(大图片可使用浏览器的本地缓存,在首次访问的时候保存到浏览器缓存中,典型的是HTML5的manifest缓存机制以及LocalStorage等)。
④ 样式表的合并:将页面样式定义、脚本、页面自己代码严格区分开,可是样式表、脚本也不是分割越细越好,由于每多引用一个样式表就增长一次HTPP请求,能合并的样式表尽可能合并。一个网站有一个公用样式表定义,每一个页面只要有一个样式表就OK啦。
B:使用内容发布网络(CDN的使用)
它是一组分布在多个不一样地理位置的Web服务器,用于更加有效地向用户发布内容。主要用于发布页面静态资源:图片、css文件、js文件等。如此,能轻易地提升响应速度。
C:添加Expires头
浏览器使用缓存来减小HTTP请求的数据,并减少HTTP响应的大小,使页面加载更快。其实就是一句话,把一些css、js、图片在首次访问的时候所有缓存到浏览器本地。(可使用HTML5提供的本地缓存机制)
D压缩组件(使用Gzip方式)
使用各类压缩工具进行对css和js的压缩,甚至能够压缩html。文件压缩变小,天然能够提高。
E:将CSS样式表放在顶部
若是将css样式定义放在页面中或者页面底部,会出现短暂白屏或者某一区域短暂白板的状况,这和浏览器的运营机制有关的,无论页面如何加载,页面都是逐步呈现的。因此在每作一个页面的时候,用Link标签把每个样式表定义放在head中。
F:将javascript脚本放在底部
浏览器在加载css文件时,页面逐步呈现会被阻止,直到全部css文件加载完毕,因此要把css文件的引用放到head中去,这样在加载css文件时不会阻止页面的呈现。可是对于js文件,在使用的时候,它下面全部的页面内容的呈现都会被阻塞,将脚本放在页面越靠下的地方,就意味着越多的内容可以逐步呈现。
G:避免使用CSS表达式
CSS表达式是动态玩CSS的一种很强大的方式,可是强大的同时也存在很高的危险性。由于css表达式的频繁求值会致使css表达式性能低下。若是真想玩css表达式,能够选用只求值一次的表达式或者使用事件处理来改变css的值。
H:使用外部javascript和CSS
内联js和css其实比外部文件有更快的响应速度,那为何还要用外部呢?由于使用外部的js和css可让浏览器缓存他们,这样不只HTML文档大小减小,并且不会增长HTTP请求数量。另外,使用外部js和css能够提升组件的可复用性。
I:减小DNS查询
DNS查询有时间开销,一般一个浏览器查找一个给定主机名的IP地址须要20-120ms。缓存DNS:缓存DNS查询能够很好地提升网页性能,一旦缓存了DNS查询,以后对于相同主机名的请求就无需进行再次的DNS查找,至少短期内不须要。因此在使用页面中URL、图片、js文件、css文件等时,不要使用过多不一样的主机名。
J:精简javascript
其实W3Cfuns已经给你们准备好精简JS所需的全部工具“前端神器”,这点W3Cfuns为你们作的很不错,在这个规则里咱们就用到“JS压缩/混淆/美化工具”最初始的精简方式:就是移除没必要要的字符减少js文件大小,改善加载时间。包括全部的注释、没必要要的空白字符。
高级一点的精简方式就是:混淆。它不但会移除没必要要的字符,还会改写代码,好比函数和变量的名字会被改为很短的字符串,这样使js代码更简练更难阅读。一旦使用混淆,对于js代码的维护和调试都很复杂,由于有时候混淆以后的js代码彻底看不懂。其实实际开发过程当中,从文件大小和代码可复用性来讲,不只仅是js代码须要精简,css代码同样也很须要精简。
K:避免重定向
重定向的英文是Redirect,用于将用户从一个URL从新跳转到另外一个URL。最多见的Redirect就是301和302两种。关于重定向的性能影响这里就不说了,自行查阅相关资料吧。在咱们实际开发中避免重定向最简单也最容易被忽视的一个问题就是,设置URL的时候,最后的“/”,有些人有时候会忽略,其实你少了“/”,这时候的URL就被重定向了,因此在给页面连接加URL的时候切记最后的“/”不可丢。
L:删除重复脚本
重复的js代码除了有没必要要的HTTP请求以外,还会浪费执行js的时间。将你使用的js代码模块化,能够很好地避免这个问题,至于js模块化如何实现,如今有不少可使用的开源框架。
M:配置ETag
Etag(Entity Tag),实体标签,是Web服务器和浏览器用户确认缓存组件的有效性的一种机制。写的很复杂,对我这种非专业的前端开发人员来讲,有点过了,关于这个原则有兴趣的本身看吧。
N:使Ajax可缓存
针对页面中主动的Ajax请求返回的数据要缓存到本地,固然这个是针对短时间内不会变化的数据。若是不肯定数据变化周期的话,能够增长一个修改标识的判断,我正常处理过程当中会给一些Ajax请求返回的数据增长一个MD5值的判断,每次请求会判断当前MD5是否变化,若是变化了取最新的数据,若是不变化,则不变。
噼里啪啦说了一堆,14个规则啊,那咱们开发过程当中要针对这每个规则对本身的前端代码作check吗?我反正不这么干,作前端页面,尤为是移动网站的页面,我所记住的准则就是:尽可能减小页面大小,尽可能下降页面响应时间。在页面性能和交互设计之中找平衡点。
(8)判断字符串是不是这样组成的,第一个必须是字母,后面能够是字母、数字、下划线,总长度为5-20.
var pattern = /^[a-zA-Z][\w]{4,19}$/igm;
var str = 'a23_dfds_dfdfd';
alert(pattern.test(str));
(9)截取字符串abcdefg的efg
var pattern = /efg/igm; var str = 'abcdefgefgefg'; if (pattern.test(str)) { //检测是否有efg alert(str.substr(str.indexOf('efg'), 3)); //取出长度为3 }
(10) 将构造函数看成函数
function Box(name, age) { this.age = age; this.name = name; this.run = function () { return this.name + this.age + "runing...."; }; }; //建立一个对象,正常调用。 var box = new Box('hg', 123); alert(box.run()); //全局运行这个函数,属性和方法添加给window,this是指向global的指针 Box('wj', 223); alert(this.run()); alert(window.run()); //在o对象中调用Box,因此o就具备了Box的属性 var o = {}; Box.call(o, 'lz', 123); alert(o.run());
(11)判断一个字符窜中出现最多的字符
var str = 'dffjkjdsfkldsfknnjfknkjfdsfdsfn'; var obj = {}; function hasMostStr(str) { var pattern = /^[\w]+/igm; if (!pattern.test(str)) return ; for (var i = 0; i != str.length; i++) { var charector = str.charAt(i); if (typeof charector!= 'string') break; if (!(charector in obj)) { obj[charector] = 1; } else { obj[charector]++; } } } function writeObj(obj) { if (typeof obj != 'object') { return; } var documents = ""; for (var pro in obj) { documents += pro + " = " + obj[pro] + "<br />"; } document.write(documents); } hasMostStr(str); writeObj(obj);
(12)规避javascript多人开发函数重名问题
(1) 能够开发前规定命名规范,根据不一样开发人员开发的功能在函数前加前缀。
(2) 将每一个开发人员的函数封装到类中,调用的时候就调用类的函数,即便函数重名只要类名不重复就能够。
(13)JavaScript继承有哪两种形式形式,进行描述
对象冒充:在子类构造方法内,经过apply/call将this做为参数传入。
优势:
能够向父类构造方法传递参数,即给apply第二个参数:arguments;
父类中的属性都被复制到子类实例中,属性之间无干扰,不管是引用类型仍是封装类型。
缺点:
每个实例对象都拥有一份父类方法的拷贝,互不干扰,因此没法统一修改;
没法拥有父类原型中定义的方法;
子类的实例对象不能经过 instanceof 操做符判断是不是父类的实例。
原型链:指定子类的prototype为父类的一个实例对象。
优缺点和构造函数借用恰好相反。
这里特别说明下属性之间相互干扰(对应构造函数借用的优势2)。
组合式继承:
上面两种方式互补一下,即用构造方法借用来继承父类属性,用原型链来继承父类方法。
优势:
封装保护了内部数据的完整性;
封装使对象的重构更轻松;
弱化模块间的耦合,提升对象的可重用性;
有助于避免命名空间冲突。
缺点:
私用方法很难测试;
必须与复杂的做用域链打交道,使错误调度更困难;
容易造成过分封装;
JavaScript并不原生支持封装,因此在JavaScript中实现封装存在复杂性的问题。
(14)编写一个方法,求一个字符串的字节长度。
function GetBytes(str) {
var len = str.length;
var bytes = len;
for (var i = 0; i < len; i++)
{
if (str.charCodeAt(i) > 255) //中文都大于255
bytes++;
}
return bytes;
}
alert(GetBytes("你好,as")); //7
charCodeAt和charAt相似,前者返回uncode编码,后者返回字符。
(15)编写一个方法 去掉一个数组的重复元素
var arr = [1,2,3,4,5,1,3,2,3,4,2,2]; function haveUnqueArray(arr) { var o = []; for (var pro in arr) { var temp = arr[pro]; if (!o[temp]) { //判断元素是否在数组中。 o.push(temp); //再也不就添加 } } return o; } alert(haveUnqueArray(arr));
(16)写出this的典型应用
1---在html元素事件属性中使用,如 <input type=”button” onclick="showInfo(this);" value="点击一下"/> 2---构造函数 function Animal(name, color) { this.name = name; this.color = color; } 3---内联的script中 <input type="button" id="text" value="点击一下" /> <script type="text/javascript"> var btn = document.getElementById("text"); btn.onclick = function() { alert(this.value); //此处的this是按钮元素--弹出点击一下 } </script>
4---CSS expression表达式中使用this关键字 <table width="100px" height="100px"> <tr> <td> <div style="width:expression(this.parentNode.width);">div element</div> </td> </tr> </table>
(17)JavaScript中如何检测一个变量是一个String类型?请写出函数实现。
String类型有两种生成方式:
(1)Var str = “hello world”; //string类型
(2)Var str2 = new String(“hello world”); //对象生成的
function IsString(str){
return (typeof str == "string" || str.constructor == String);
}
var str = "";
alert(IsString(1));
alert(IsString(str));
alert(IsString(new String(str)))
(18)JavaScript事件委托的技术原理
事件委托,就是事件,好比onclick,onmouseover,onmouseout.委托的意思就是让别人来作,
原理就是利用冒泡的原理,把事件加载到父级标签上,触发执行效果。
好处1:提升性能。不须要for循环为每个元素都加入事件。
好处2,新添加的元素还会有以前的事件。极可能此时js已经加载完成了,新加入的节点没法在作出反应事件了,就还须要从新加载一次js。
其实要是对属性作操做,事件委托,就能够代替闭包和添加新的属性,来解决对元素的循环操做。而且提高了性能。
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
<script>
// 找到父元素,添加监听器...
//这里只写了W3C的,IE是attachEvent
document.getElementById("parent-list").addEventListener("click", function(ev) {
// e.target是被点击的元素!
// 若是被点击的是li元素
// var ev = ev || window.event;
// var target = ev.target || ev.srcElement;
if(ev.target && ev.target.nodeName == "LI") {
// 找到目标,输出ID!
// console.log("List item ",ev.target.id.substr(ev.target.id.length - 1)," was clicked!");
alert("List item " + ev.target.id.substr(ev.target.id.length - 1));
}
}, false);
</script>
(19)JS添加事件
第一种: obj.onclick = method1;
obj.onclick = method2;
obj.onclick = method3; 最后只有medthod3保存了
第二种:用addEventListener(‘click’, function, false);
False 是由里向外,true是由外向内。
IE还有一个attachEvent(‘click’, function);
第三种写法 : obj['onclick']或者obj['click'] = function () {};
IE要加on W3C,就不加。
(20)冒泡事件是什么?如何阻止事件冒泡和默认事件。
事件冒泡: 当一个元素上的事件被触发的时候,好比说鼠标点击了一个按钮,一样的事件将会在那个元素的全部祖先元素中被触发。这一过程被称为事件冒泡;
这个事件从原始元素开始一直冒泡到DOM树的最上层。
阻止冒泡事件: cancelBubble(IE)和stopPropagation(FF)
function doSomething (obj, evt) {
alert(obj.id);
var e = (evt) ? evt : window.event;
//判断浏览器的类型,在基于ie内核的浏览器中的使用cancelBubble
if (window.event)
{
e.cancelBubble=true;
}
else
{
//e.preventDefault(); //在基于firefox内核的浏览器中支持作法stopPropagation
e.stopPropagation();
}
}
w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
阻止默认行为
w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;
(21)解释jsonp的原理,以及为何不是真正的ajax
动态建立script标签,回调函数,Ajax是页面无刷新请求数据操做。
JSONP(JSON with Padding)是JSON的一种“使用模式”,
可用于解决主流浏览器的跨域数据访问的问题。
因为同源策略,通常来讲位于 server1.example.com 的网页没法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。
利用 <script> 元素的这个开放策略,网页能够获得从其余来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。
用 JSONP 抓到的资料并非 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
(22)javascript的本地对象,内置对象和宿主对象
本地对象:
Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
由此能够看出,简单来讲,本地对象就是 ECMA-262 定义的类(引用类型)
内置对象:
ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每一个内置对象都是本地对象)。
本地对象,就是那些官方定义好了的对象。内置对象是本地对象的一种,其只包含Global对象和Math对象。而宿主对象则是那些官方未定义,你本身构建的对象加上DOM和BOM对象组成的。
(23)document load 和document ready的区别
Document.onload 是在结构和样式加载完才执行js
Document.ready原生种没有这个方法,jquery中有$().ready(function)DOM结构绘制完毕后就执行,没必要等到加载完毕。
执行时间
window.onload 必须等到页面内包括图片的全部元素加载完毕后才能执行。
$(document).ready() 是DOM结构绘制完毕后就执行,没必要等到加载完毕。
编写个数不一样
window.onload 不能同时编写多个,若是有多个window.onload方法,只会执行一个
$(document).ready() 能够同时编写多个,而且均可以获得执行
简化写法
window.onload 没有简化写法
$(document).ready(function(){}) 能够简写成$(function(){});
(24)简述JavaScript封装。
封装能够被定义为对对象的内部数据表现形式和实现细节进行隐藏。经过封装能够强制实施信息隐藏。
在JavaScript中,并无显示的声明私有成员的关键字等。
因此要想实现封装/信息隐藏就须要从另外的思路出发。咱们可使用闭包的概念来建立只容许从对象内部访问的方法和属性,来达到封装的要求。
基本方式
通常来讲,咱们学用的有三种方法来达到封装的目的。
使用this.XXX来声明一个变量,而后再声明getXXX、setXXX等取值、赋值的方法。
使用this._XXX来声明一个变量,而后再声明getXXX、setXXX等取值、赋值的方法。
利用“函数做用域”这一个概念来作。 1. 门户大开型 var Book = function(val){ this.setValue(val); }; Book.prototype = { setValue: function(val){ this.val = val; }, getValue: function(){ return this.val; }, }; var book = new Book(1); alert(book.val);
使用这种方法实现的封装,虽然实现了取值器与赋值器以保护私有属性。可是在实际使用中,私有属性依然能够从外部访问,因此从根本上讲,没有实现封装。
2. 用命名规范进行区别 var Book = function(val){ this.setValue(val); }; Book.prototype = { setValue: function(val){ this._val = val; }, getValue: function(){ return this._val; }, }; var book = new Book(1); alert(book._val); 使用这种方法与第一种相似,区别在于使用不一样的命名来保护私有属性的使用。可是,从实际应用来讲其仍然没有实现封装。 3. 使用函数做用域 var Book = function() { var isbn; //这里是局部变量。函数做用域。 this.setIsbn = function(newIsbn){ isbn = newIsbn; }; this.getIsbn = function(){ return isbn; }; } var book = new Book(); book.setIsbn(1); alert(book.getIsbn()); 因为在JavaScript的函数中声明的变量是有做用域的,因此使用这种方法能够避免在外部直接访问私有属性。基本达到封装所要求的内容。 这里要注意的是,咱们在函数的内部,可使用this.XXX以及var来声明变量。区别是使用this.XXX声明的变量在外部是能够访问的。
使用var声明的变量,因为受到函数做用域的保护,在函数的外部是没法直接访问的。
(25)Js中this具体的用法总结以下
1. 全局变量和全局函数附属于全局对象(window),所以使用”var”或”this”两种方法定义全局变量是等效的。
2. 执行上下文和做用域不一样。执行上下文在运行时肯定,随时可能改变,而做用域则在定义时肯定,永远不会变。这个跟MFC的一个性质很像,运行时动态识别。
//获取对象构造函数名称 function type(obj) { return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)/)[1]; } function test() { alert(type(this)); } function A() { this.fun = test; } function B() { this.fun = test; } var a = new A(); var b = new B(); test(); // window a.fun(); // A b.fun(); // B
3. 若是当前执行的是一个对象的方法,则执行上下文就是这个方法所附属的对象。
function test () { alert(this.name); } function AAA() { this.name = 'hg'; this.test1 = test; function BBB() { this.name = 'gh'; this.test2 = test; } this.bbb = new BBB(); } var aaa = new AAA(); aaa.test1(); //hg aaa.bbb.test2(); //gh
说明,函数test中的this指向临近的这个对象。这个对象方法,执行的就是上下文所对应的对象。
4. 若是当前是一个建立对象的过程或者执行一个对象的方法,则执行上下文就是这个正在被建立的对象。
5. 若是一个方法在执行时没有明确指定附属对象,则这个方法的上下文为全局对象。
6. 使用call和apply能够改变对象的执行上下文。
(26)简述下cookie的操做,还有cookie的属性都知道哪些。
cookie是浏览器提供的一种机制,它将document 对象的cookie属性提供给JavaScript。
能够由JavaScript对其进行控制,而并非JavaScript自己的性质。cookie是存于用户硬盘的一个文件,这个文件一般对应于一个域名,当浏览器再次访问这个域名时,便使这个cookie可用。
所以,cookie能够跨越一个域名下的多个网页,但不能跨越多个域名使用。可用在保存用户登陆状态。跟踪用户行为。定制页面。建立购物车。
$.cookie(‘cookieName’,'cookieValue’,{expires:7,path:’/',domain: ‘chuhoo.com’,secure: false,raw:false});
注:expires:有效时间;path:设置可以读取cookie的顶级目录;domain: 建立cookie所在网页所拥有的域名;secure:默认是false,若是为true,cookie的传输协议需为https;raw:默认为 false,读取和写入时候自动进行编码和解码(使用encodeURIComponent编码,使用decodeURIComponent解码),关闭 这个功能,请设置为true。
(27)前端优化知识都知道哪些?
答:a 减小http请求,合并css、js文件,apache的ant。
b 减小请求文件的大小,压缩css、js文件,在线javascript compress。
c 采用sprite拼接图片。
d 若是有广告栏之类的模块,用iframe。
e 将js文件放到末尾,这个页面显示就没必要等js文件加载完之后再显示,也就是页面不会出现空白状态。
(28)瀑布流布局或者流式布局是否有了解。
答:瀑布流布局:采用绝对定位来给每张图片或者模块定位。
流式布局:采用浮动式给模块定位。能够作出响应式布局。
(29)JavaScript中如何对一个对象进行深度clone
克隆方法实在不少,这里只是举例一个。
function cloneObject(o) { if(!o || 'object' !== typeof o) { return o; } var c = 'function' === typeof o.pop ? [] : {}; var p, v; for(p in o) { if(o.hasOwnProperty(p)) { v = o[p]; if(v && 'object' === typeof v) { c[p] = Ext.ux.clone(v); } else { c[p] = v; } } } return c; };
(30)请实现,鼠标点击页面中的任意标签,alert该标签的名称.(注意兼容性)
<script type="text/javascript"> document.onclick = function(evt){ var e = window.event || evt; var tag = e["target"] || e["srcElement"]; alert(tag.tagName); }; </script>
(31)做用域的问题
(1)var a = 6;
setTimeout(function () {
alert(a);
a = 666;
}, 1000);
a = 66;
Alert是打印66的,由于1s以后,a==66。三个a都是全局变量。
(2)
var a = 6;
SetTimeout(function () {
alert(a);
var a = 666;
}, 1000);
a = 66;
打印的是undefined,由于在function内部又定义了var的局部变量。
还有一点要记住:setTimeout(function,time);function是一个全局的函数。就是this。Function()这个this是全局不是某一个对象。
var a = 0; //定义全局变量 function A(){ this.a = 1; //对象变量a setTimeout(function(){ //函数和变量执行的是全局做用域 this.a = 2; //this 指向的是全局做用域 a=2 try{ this.b="b"; throw ''; //这里抛出了一个异常 } catch(e){ this.b='bb'; //全局的b设置为bb } },0); this.b = "bbb"; //定义对象内的b变量 } var aa = new A(); //定义了对象,运行了setTimeout setTimeout(function(){ console.log(aa.a); //1 console.log(window.a); //2 console.log(aa.b); //bbb console.log(window.b) //bb },0);
(32) 判断输出
var a = 10; function bb () { alert(a); var a=2; alert(a); } bb();
undefined
2