编写一个方法 求一个字符串的字节长度
假设:一个英文字符占用一个字节,一个中文字符占用两个字节javascript
function GetBytes(str){ var len = str.length; var bytes = len; for(var i=0; i<len; i++){ if (str.charCodeAt(i) > 255) bytes++; } return bytes; } alert(GetBytes("你好,as"));
实现一个函数clone,能够对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制css
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; }
79.冒泡排序、快速排序、去重、查找字符串最多值html
//冒泡排序 var bubbleSort = function(arr) { for (var i = 0; i < arr.length-1; i++) { for (var j = i+1; j < arr.length; j++) { if (arr[i]>arr[j]) { var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } return arr; }; //快速排序 var quickSort = function(arr) { if (arr.length <= 1) { return arr; } var len = arr.length; var midIndex = Math.floor(len/2); var mid = arr.splice(midIndex,1); var left = []; var right = []; for (var i = 0; i < arr.length; i++) { if (arr[i] < mid) { left.push(arr[i]); } else { right.push(arr[i]); } } return quickSort(left).concat(mid,quickSort(right)) } // 去重 var distinct = function(arr) { var map = {}; var result = []; for (var i = 0; i < arr.length; i++) { if (!map[arr[i]]) { map[arr[i]] = true; result.push(arr[i]); } } return result; } //查找字符串中最多的值 var search = function(str) { var json = {}; var max = 0; var char; for (var i = 0; i < str.length; i++) { if (!json[str[i]]) { json[str[i]]=1; } else { json[str[i]]++; } } console.log(json); for(var i in json){ if(json[i]>max){ max = json[i]; char = i; } } console.log(max, char); }
80.函数组合继承前端
原型继承、构造函数继承、call aplly继承html5
var Super = function(name){ this.name = name; } Super.prototype.func1 = function() { console.log('func1'); } var Sub = function(name,age) { Super.call(this, name); this.age = age; } Sub.prototype = new Super();
81.事件绑定java
var addEvent = function(e, type, handler, capture ) { if (e.addEventListener) { e.addEventListener(type, handler, capture); } else if (e.attachEvent) { e.attachEvent('on'+type, handler); } else { e['on'+type] = handler; } }
82.浅克隆和深度克隆git
//浅克隆 function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; } //深度克隆 var clone = function(v) { var o = v.constructor === Array ? [] : {}; for (var i in v) { o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i]; } return o; }
83.实现一个秒针绕一点转动的效果github
animation: move 60s infinite steps(60); /*设置旋转的中心点为中间底部*/ transform-origin: center bottom; /*旋转从0度到360度*/ @keyframes move { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
72.生成10个20-50之间的随机数,存在数组中,常见排序方法,数组乱序方法web
var arr = []; for(var i = 0;i<10;i++){ var num = Math.random()*30 + 20; num = parseInt(num, 10); arr.push(num); } arr.sort(function(a,b){ return 0.5 - Math.random(); })
69.实现一个once函数面试
function test () {console.log('test')} var once = function (fn) { var isFirst = true; return function () { if (isFirst) { isFirst = !isFirst; fn(); } }; }; var b = once(test); b(); // 'test' b(); // nothing
65.两个数组合并成一个数组排序返回
先依次比较两个数组,按照小的就传入新的数组。当此次比较完以后可能有一个数组的长度很长,留下一些数组,而后在新数组的末尾插入便可。
functiongetRes(arr1, arr2){ var len1 = arr1.length, len2 = arr2.length, i = 0, j = 0, k = 0, res = new Array(len1+len2); while(i < len1 && j <len2){ res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++]; } While(i < len1) res[k++]= arr1[i++]; While(j < len2) res[k++]= arr2[j++]; Return res; }
62.将url的查询参数解析成字典对象
function getQueryObject(url) { url = url == null ? window.location.href : url; var search = url.substring(url.lastIndexOf("?") + 1); var obj = {}; var reg = /([^?&=]+)=([^?&=]*)/g; search.replace(reg, function (rs, $1, $2) { var name = decodeURIComponent($1); var val = decodeURIComponent($2); val = String(val); obj[name] = val; return rs; }); return obj; } getQueryObject("http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**") Object {name: "1", dd: "ddd**"}
53:图片预加载和懒加载
预加载:
function loadImage(url, callback) { var img = new Image(); img.src = url; if (img.complete) { // 若是图片已经存在于浏览器缓存,直接调用回调函数 防止IE6不执行onload BUG callback.call(img); return; } img.onload = function () { callback.call(img);//将回调函数的this替换为Image对象 }; };
懒加载:
当网页滚动的事件被触发 -> 执行加载图片操做 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。
var aImages = document.getElementById("SB").getElementsByTagName('img'); //获取id为SB的文档内全部的图片 loadImg(aImages); window.onscroll = function() { //滚动条滚动触发 loadImg(aImages); }; //getBoundingClientRect 是图片懒加载的核心 function loadImg(arr) { for(var i = 0, len = arr.length; i < len; i++) { if(arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad) { arr[i].isLoad = true; //图片显示标志位 //arr[i].style.cssText = "opacity: 0;"; (function(i) { setTimeout(function() { if(arr[i].dataset) { //兼容不支持data的浏览器 aftLoadImg(arr[i], arr[i].dataset.imgurl); } else { aftLoadImg(arr[i], arr[i].getAttribute("data-imgurl")); } arr[i].style.cssText = "transition: 1s; opacity: 1;" //至关于fadein }, 500) })(i); } } } function aftLoadImg(obj, url) { var oImg = new Image(); oImg.onload = function() { obj.src = oImg.src; //下载完成后将该图片赋给目标obj目标对象 } oImg.src = url; //oImg对象先下载该图像 }
46:圣杯布局和双飞翼布局
【圣杯布局】
html代码中 middle部分首先要放在container的最前部分。而后是left,right
1.将三者都 float:left , 再加上一个position:relative (由于相对定位后面会用到)
2.middle部分 width:100%占满
3.此时middle占满了,因此要把left拉到最左边,使用margin-left:-100%
4.这时left拉回来了,但会覆盖middle内容的左端,要把middle内容拉出来,因此在外围container加上 padding:0 220px 0 200px
5.middle内容拉回来了,但left也跟着过来了,因此要还原,就对left使用相对定位 left:-200px 同理,right也要相对定位还原 right:-220px
6.到这里大概就自适应好了。若是想container高度保持一致能够给left middle right都加上min-height:130px
【双飞翼布局】
前几步都同样 后边把外围padding和相对定位作法换成内层margin
给middle增长一个内层div-- middle-inner, 而后margin:0 220px 0 200px
39: 写一个组合继承
var Super = function(name){ this.name = name; } Super.prototype.func1 = function() { console.log('func1'); } var Sub = function(name,age) { Super.call(this, name); this.age = age; } Sub.prototype = new Super();
40:深拷贝方案有哪些,手写一个深拷贝
var clone = function(v) { var o = v.constructor === Array ? [] : {}; for (var i in v) { o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i]; } return o; }
实现两栏布局有哪些方法
*{margin:0; padding: 0;} html,body{ height: 100%;/*高度百分百显示*/ } #left{ width: 300px; height: 100%; background-color: #ccc; float: left; } #right{ height: 100%; margin-left: 300px; background-color: #eee;
*{margin:0; padding: 0;} html,body{ height: 100%;/*高度百分百显示*/ } #left{ width: 300px; height: 100%; background-color: #ccc; float: left; } #right{ height: 100%; overflow:hidden; background-color: #eee; }
第二种方法,我利用的是建立一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。它能够经过如下任何一种方式来建立:
float 的值不为 none
position 的值不为 static 或者 relative
display 的值为 table-cell , table-caption , inline-block , flex , 或者 inline-flex 中的其中一个
overflow 的值不为 visible
第三种flex布局
在一个UI里有10个li,实现点击对应的li,输出对应的下标
var lis = querySelectorAll('li') for(var i=0;i<10;i++){ lis[i].onclick = (function(a) { return function() { alert(a) } })(i) }
如何取出一个数组里的图片并按顺序显示出来?
function loadImage(imgList,callback){ if(!$.isArray(imgList) || !$.isFunction(callback)) return ; var imageData = [] ; $.each(imgList, function(i,src){ var img = new Image() ; img.onload = function(){ $(imageData.shift()).appendTo("body") ; if(!imageData.length){ callback() ; return ; } this.onload = null ; } ; img.src= src ; imageData.push(img) ; }) ; } ;
如何在页面上实现一个圆形的可点击区域?三种解决方案。
1. map+area
使用Dreamweaver制做热点会变得很是的容易,最终会造成上面的代码,具体的操做,能够参考视频,http://www.chuanke.com/3885380-190205.html。
2. border-radius(H5)
运行效果
3. 纯js实现
须要求一个点在不在圆上简单算法、获取鼠标坐标等等
两点之间的距离计算公式
上面公式对于JavaScript代码以下:
|AB|=Math.abs(Math.sqrt(Math.pow(X2-X1),2)+Math.pow(Y2-Y1,2)))
Math.abs()求绝对值Math.pow(底数,指数)
Math.sqrt()求平方根
示例:假设圆心为(100,100),半径为50,在圆内点击弹出相应的信息,在圆外显示不在圆内的信息
document.onclick=function(e){ var r=50;//圆的半径 var x1=100,y1=100,x2= e.clientX;y2= e.clientY; //计算鼠标点的位置与圆心的距离 var len=Math.abs(Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2))); if(len<=50){ console.log("内") }else{ console.log("外") } }
一 、流式布局
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>流式布局</title> <style type="text/css"> body { margin: 0; } .reddiv { width: 30%; /* 单位 vw ViewWidth vh ViewHeight */ height: 30vw; background-color: red; } .big { } .big span { font-size: 2em; } </style> </head> <body> <!-- 流式布局 百分比布局 1、宽高设置百分比 2、宽高设置VW VH 3、弹性图片(给宽度,高度会自适应,不失真) 四、em/rem(都是倍数,em相对于父级,rem相对于html) --> <!-- <div class="reddiv"></div> --> <img src="http://img.taopic.com/uploads/allimg/121009/235045-12100Z31P150.jpg" width="50%" alt=""> <div class="big"> <span>我是span标签</span> </div> </body> </html>
2、响应式布局
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>响应式布局</title> <style type="text/css"> /* @media 媒体查询、媒体选择 screen 屏幕 and 后面跟条件 */ /* 经过媒体查询能够设置多套布局,具体使用哪一套,就是根据媒体查询的条件来定(条件就是and后面的括号and 和括号之间要有空格) */ @media screen and (max-width:150px) { .div1 { background-color: gold; } } @media screen and (min-width: 150px) and (max-width:300px) { .div1 { background-color: red; } } @media screen and (min-width: 300px) and (max-width:600px) { .div1 { background-color: blue; } } @media screen and (min-width: 600px) and (max-width:900px) { .div1 { background-color: green; } } @media screen and (min-width: 900px) and (max-width:1200px) { .div1 { background-color: pink; } } @media screen and (min-width:1200px) { .div1 { background-color: black; } } .div1 { width: 400px; height: 400px; } </style> </head> <body> <div class="div1"></div> </body> </html>
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>viewport</title> <!-- viewport 可视区域 width 宽度,能够理解为设置咱们的网页一个屏幕能看到的宽度 maximum-scale 放大的最大值(网页能放大几倍) minimum-scale 缩小的倍数(网页最小能缩小多少倍) initial-scale=1.0 页面初始值(通常是1.0) user-scalable=0 是否容许用户缩放(1能够,0不能够) (苹果设备,须要的图片像素通常是物理像素的2倍,或3倍) target-densitydpi 值越高看的越清楚 device-dpi 设备本来的dpi high-dpi 高dpi low-dpi 低dpi value 指定一个具体数值,取值范围 70 - 400 --> <meta name="viewport" content="width=device-width,maximum-scale=2.0,minimum-scale=1.0,initial-scale=1.0,user-scalable=1,target-densitydpi=high-dpi"> <style type="text/css"> body { margin: 0; } .reddiv { width: 210px; height: 80px; background-color: red; border: 1px solid blue; } </style> </head> <body> <label for="name">姓名</label> <input type="text" id="name"/> <div class="reddiv"></div> </body> </html>
JavaScript开发人员在IT界的需求量一直很大。若是你很是精通神这门语言,你会有不少机会换工做,涨薪水。可是在一家公司录用你以前,你必须顺利经过面试,证实你的技能。在本文中,我将向您展现5个关于前端相关的问题,以测试侯选者的JavaScript技能和他们解决问题的能力。有将会很是有趣!
问题1:Scope做用范围
考虑下面的代码:
(function() {
var a = b = 5;
})();
console.log(b);
什么会被打印在控制台上?回答上面的代码会打印5。这个问题的诀窍是,这里有两个变量声明,但a使用关键字
var声明的。表明它是一个函数的局部变量。与此相反,b变成了全局变量。这个问题的另外一个诀窍是,它没有使用严格模式 ('use strict';)。若是启用了严格模式,代码就会引起ReferenceError的错误:B没有定义(b is not defined)。请记住,严格模式,则须要明确指定,才能实现全局变量声明。好比,你应该写:
(function() {
'use strict';
var a = window.b = 5;
})();
console.log(b);问题2:建立“原生”(native)方法
给字符串对象定义一个repeatify功能。当传入一个整数n时,它会返回重复n次字符串的结果。例如:
console.log('hello'.repeatify(3));
应打印hellohellohello。回答一个可能的实现以下所示:
String.prototype.repeatify = String.prototype.repeatify ||
function(times) {
var str = '';
for (var i = 0; i < times; i++) {
str += this;
}
return str;
};
如今的问题测试开发者有关JavaScript继承和prototype的知识点。这也验证了开发者是否知道该若是扩展内置对象(尽管这不该该作的)。这里的另外一个要点是,你要知道如何不覆盖可能已经定义的功能。经过测试一下该功能定义以前并不存在:
String.prototype.repeatify = String.prototype.repeatify ||
function(times) {
/* code here */
};
当你被要求作好JavaScript函数兼容时这种技术特别有用。
问题3:声明提高(Hoisting)
执行这段代码,输出什么结果。
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
回答这段代码的结果是undefined和2。缘由是,变量和函数的声明都被提早了(移到了函数的顶部),但变量不分配任何值。所以,在打印变量的时候,它在函数中存在(它被声明了),但它仍然是undefined。表示换句话说,上面的代码等同于如下内容:
function test() {
var a;
function foo() {
return 2;
}
console.log(a);
console.log(foo());
a = 1;
}
test();
问题4:this在JavaScript中如何工做的
下面的代码会输出什么结果?给出你的答案。
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
回答答案是Aurelio De Rosa和John Doe。缘由是,在一个函数中,this的行为,取决于JavaScript函数的调用方式和定义方式,而不只仅是看它如何被定义的。在第一个console.log()调用中,getFullname()被调用做为obj.prop对象的函数。因此,上下文指的是后者,函数返回该对象的fullname。与此相反,当getFullname()被分配到test变量时,上下文指的是全局对象(window)。这是由于test是被隐式设置为全局对象的属性。出于这个缘由,该函数返回window的fullname,即定义在第一行的那个值。
问题5:call()和apply()
如今让你解决前一个问题,使最后的console.log()打印Aurelio De Rosa。回答该问题能够经过强制使用call()或者apply()改变函数上下文。在下面我将使用call(),但在这种状况下,apply()会输出相同的结果:
console.log(test.call(obj.prop));结论
在这篇文章中,咱们已经讨论了用来测试JavaScript开发者的五个经典问题。面试的概念和涵盖的主题一般是很是类似的。若是你不知道的一些问题的答案,没必要担忧:学习和经验能够慢慢积累。若是你有其余一些有趣的问题,不要犹豫,与咱们分享。它会帮助不少开发者。
11.b继承a的方法12.写一个获取非行间样式的函数
function getStyle(obj, attr, value)
{
if (!value)
{
if (obj.currentStyle)
{
return obj.currentStyle(attr);
}
else
{
obj.getComputedStyle(attr, false);
}
}
else
{
obj.style[attr] = value;
}
}
22.编写一个数组去重的方法
function oSort(arr) {
var result = {};
var newArr = [];
for (var i = 0; i < arr.length; i++)
{
if (!result[arr[i]])
{
newArr.push(arr[i]);
result[arr[i]] = 1;
}
}
return newArr;
}
23.排序算法
“快速排序”的思想很简单,整个排序过程只须要三步:
(1)在数据集之中,找一个基准点
(2)创建两个数组,分别存储左边和右边的数组
(3)利用递归进行下次比较
function quickSort(arr){ if(arr.length<=1){ return arr;//若是数组只有一个数,就直接返回; } var num = Math.floor(arr.length/2);//找到中间数的索引值,若是是浮点数,则向下取整 var numValue = arr.splice(num,1);//找到中间数的值 var left = []; var right = []; for(var i=0;i<arr.length;i++){ if(arr[i]<numValue){ left.push(arr[i]);//基准点的左边的数传到左边数组 } else{ right.push(arr[i]);//基准点的右边的数传到右边数组 } } return quickSort(left).concat([numValue],quickSort(right));//递归不断重复比较 } alert(quickSort([32,45,37,16,2,87]));//弹出“2,16,32,37,45,87”
/**冒泡排序 */
function bubbleSort() {
var array = [5, 4, 3, 2, 1];
var temp = 0;
for (var i = 0; i < array.length; i++)
{
for (var j = 0; j < array.length - i; j++)
{
if (array[j] > array[j + 1])
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
(内容3)——————
http: //bbs.blueidea.com/thread-3107428-1-1.html如下都是网上整理出来的JS面试题,答案仅供参考。
2,截取字符串abcdefg的efg alert('abcdefg'.substring(4));
3,判断一个字符串中出现次数最多的字符,统计这个次数
var str = 'asdfssaaasasasasaa';
var json = {};
for (var i = 0; i < str.length; i++) {
if (!json[str.charAt(i)]) {
json[str.charAt(i)] = 1;
} else {
json[str.charAt(i)]++;
}
};
var iMax = 0;
var iIndex = '';
for (var i in json) {
if (json[i] > iMax) {
iMax = json[i];
iIndex = i;
}
}
alert('出现次数最多的是:' + iIndex + '出现' + iMax + '次');
6,javascript面向对象中继承实现
function Person(name) {
this.name = name;
}
Person.prototype.showName = function() {
alert(this.name);
}
function Worker(name, job) {
Person.apply(this, arguments) this.job = job;
}
for (var i in Person.prototype) {
Worker.prototype = Person.prototype;
}
new Worker('sl', 'coders').showName();
7,FF下面实现outerHTML
var oDiv = document.createElement('div');
var oDiv1 = document.getElementById('div1');
var oWarp = document.getElementById('warp');
oWarp.insertBefore(oDiv, oDiv1);
oDiv.appendChild(oDiv1);
var sOut = oDiv.innerHTML;
oWarp.insertBefore(oDiv1, oDiv);
oWarp.removeChild(oDiv);
alert(sOut);
8,编写一个方法求一个字符串的字节长度假设一个中文占两个字节
var str = '22两是';
alert(getStrlen(str))
function getStrlen(str) {
var json = {
len: 0
};
var re = /[\u4e00-\u9fa5]/;
for (var i = 0; i < str.length; i++) {
if (re.test(str.charAt(i))) {
json['len']++;
}
};
return json['len'] + str.length;
}
十一、如何深度克隆
var arr = [1, 2, 43];
var json = {
a: 6,
b: 4,
c: [1, 2, 3]
};
var str = 'sdfsdf';
var json2 = clone(json);
alert(json['c']) function clone(obj) {
var oNew = new obj.constructor(obj.valueOf());
if (obj.constructor == Object) {
for (var i in obj) {
oNew[i] = obj[i];
if (typeof(oNew[i]) == 'object') {
clone(oNew[i]);
}
}
}
return oNew;
}
12,JavaScript中如何检测一个变量是一个String类型?请写出函数实现typeof(obj) == 'string'obj.constructor == String;
13,网页中实现一个计算当年还剩多少时间的倒数计时程序,要求网页上实时动态显示“××年还剩××天××时××分××秒”
var oDate = new Date();
var oYear = oDate.getFullYear();
var oNewDate = new Date();
oNewDate.setFullYear(oYear, 11, 31, 23, 59, 59);
var iTime = oNewDate.getTime() - oDate.getTime();
var iS = iTime / 1000;
var iM = oNewDate.getMonth() - oDate.getMonth();
var iDate = iS
以前在学习时把问题和答案分开了,这儿也分开吧。这样在看得时候无心识的会多思考一下。茶余饭后,来杯咖啡
["1","2","3"].map(parseInt) A.["1","2","3"] B.[1,2,3] C.[0,1,2] D.其余
map对数组的每一个元素调用定义的回调函数并返回包含结果的数组。["1","2","3"].map(parseInt)对于数组中每一个元素调用paresInt。可是该题目不一样于:
function testFuc(a){ return parseInt(a); } console.info(["1","2","3"].map(testFuc));
题目等同于:
function testFuc(a,x){ return parseInt(a,x); } console.info(["1","2","3"].map(testFuc));
map中回调函数的语法以下所示:function callbackfn(value, index, array1),可以使用最多三个参数来声明回调函数。第一参数value,数组元素的值;第二个参数index,数组元素的数组因此;array1,包含该元素的数组对象。
所以,题目等同于[parseInt(1,0),parseInt(2,1),parseInt(3,2)] 最终返回[1, NaN, NaN]。
[typeof null, null instanceof Object] A.["object",false] B.[null,false] C.["object",true] D.其余
typeof用以获取一个变量或者表达式的类型,typeof通常只能返回以下几个结果:
number,boolean,string,function(函数),object(NULL,数组,对象),undefined
instanceof 表示某个变量是不是某个对象的实例,null是个特殊的Object类型的值 ,表示空引用的意思 。但null返回object这个实际上是最初JavaScript的实现的一个错误,
而后被ECMAScript沿用了,成为了如今的标准,不过咱们把null能够理解为还没有存在的对象的占位符,这样就不矛盾了 ,虽然这是一种“辩解”。
对于咱们开发人员 仍是要警戒这种“语言特性”。最终返回:["object", false]
[[3,2,1].reduce(Math.pow),[].reduce(Math.pow)] A.报错 B.[9,0] C.[9,NaN] D.[9,undefined]
pow() 方法可返回 x 的 y 次幂的值。[3,2,1].reduce(Math.pow);等同于:
function testFuc(x,y){ console.info(x +" : "+y); return Math.pow(x,y); } console.info([3,2,1].reduce(testFuc));
执行Math.pow(3,2)和Math.pow(2,1),最终返回9和9。
可是要注意pow的参数都是必须的,[].reduce(Math.pow),等同于执行Math.pow();会致使错误。
var val = 'value'; console.info('Value id '+(val === 'value')?'Something':'Nothing'); A.Something B.Nothing C.NaN D.其余
先执行字符串拼接,再执行校验
var val = 'value'; console.info('Value id '+(val === 'value123')?'Something':'Nothing');
一样会返回something
var name = 'World'; (function(){ if(typeof name === 'undefined'){ var name = "Jack"; console.info('Goodbye '+ name); }else{ console.info('Hello ' + name); } })(); A.Goodbye Jack B.Hello Jack C.Goodbye undefined D.Hello undefined
判断语句被包裹在当即调用函数里,函数内部没法访问外部值为'World'的name,所以typeof name === 'undefined'为真,执行下一步操做,最终输出Goodbye Jack
var START = END -100; var count = 0; for(var i = START ; i <= END ;i++){ count ++; } console.info(count); A.0 B.100 C.101 D.其余
END = 9007199254740992 ,START = 9007199254740892目的是计算的END和START之间的差。可是2的53次方计算出的结果因为精度问题使得i++失效。
var arr = [0,1,2]; arr[10] = 10; arr.filter(function(x){return x === undefined}); A.[undefined x 7] B.[0,1,2,10] C.[] D.[undefined]
filter会接触到没有被赋值的元素,即在arr中,长度为10但实际数值元素列表为[0, 1, 2, 10],所以,最终返回一个空的数组[]。
var two = 0.2; var one = 0.1; var eight = 0.8; var six = 0.6; [two -one == one,eight- six == two]; A.[true,true] B.[false,false] C.[true,false] D.其余
两个浮点数相加或者相减,将会致使必定的正常的数据转换形成的精度丢失问题eight-six = 0.20000000000000007。
JavaScript中的小数采用的是双精度(64位)表示的,由三部分组成: 符 + 阶码 + 尾数,在十进制中的 1/10,在十进制中能够简单写为 0.1 ,但在二进制中,他得写成:0.0001100110011001100110011001100110011001100110011001…..(后面全是 1001 循环)。由于浮点数只有52位有效数字,从第53位开始,就舍入了。这样就形成了“浮点数精度损失”问题。
更严谨的作法是(eight-six ).totoFiexd(1)或者用用Math.round方法回归整数运算。判断两个浮点数是否相等,仍是建议用逼近的比较,好比if((a-b) < 1E-10)
function showCase(value){ switch(value){ case 'A': console.info('Case A'); break; case 'B': console.info('Case B'); break; case undefined : console.info('undefined'); break; default: console.info('Do not know!'); } } showCase(new String('A')); A.Case A B.Case B C.Do not know D.undefined
使用new String()使用构造函数调用讲一个全新的对象做为this变量的值,而且隐式返回这个新对象做为调用的结果,所以showCase()接收的参数为String {0: "A"}为不是咱们所认为的“A”
function showCase(value){ switch(value){ case 'A': console.info('Case A'); break; case 'B': console.info('Case B'); break; case undefined : console.info('undefined'); break; default: console.info('Do not know!'); } } showCase(String('A')); A.Case A B.Case B C.Do not know D.undefined
直接调用String("A")建立的变量和"A"无异。
var a="123" '只是设置变量 b=new String('123') '设置一个成员 var a="123"; a.sex=1; alert(a.sex);//输出未定义,由于不是成员,没有这属性 b=new String('123'); b.sex=1; alert(b.sex);//输出1,成员的属性
function isOdd(num){ return num % 2 == 1; } function isEven(num){ return num % 2 == 0; } function isSane(num){ return isEven(num)||isOdd(num); } var values = [7,4,'13',-9,Infinity]; values.map(isSane); A.[true, true, true, true, true] B.[true, true, true, true, false] C.[true, true, true, false, false] D.[true, true, false, false, false]
function isSane(num){ return isEven(num)||isOdd(num); }
该函数判断num是否为正整数,'13'被强制转换为数值13,-9%2结果为-1,Infinity %2为NaN
[parseInt(3,8),parseInt(3,2),parseInt(3,0)] A.[3,3,3] B.[3,3,NaN] C.[3,NaN,NaN] D.其余
最终结果为[3, NaN, 3];
parseInt() 函数可解析一个字符串,并返回一个整数。当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
Array.isArray(Array.prototype) A.true B.false C.报错 D.其余
Array.prototype为[],Array.isArray(a)是一个判断a是否为数组的方法。
判断对象是否为数组的方法:
1)ES5函数isArray(),该函数测试对象的内部[[Class]]属性是否为Array:Arrray.isArray(a);
2)判断对象的构造函数是否为Array:a.constructor === Array
3)使用对象内部[[Class]]属性建立结果字符串:Object.prototype.toString.call(a)
4)使用instanceof操做符测试对象是否继承自Array:(但因为,一个页面的iframe不会继承自另一个页面的iframe,该方法不可靠)
a instanceof Array
var a = [0]; if([0]){ console.info(a == true); }else{ console.info("false"); } A.true B.false C."else" D.其余
在if条件判断语句相对于==比较宽松中,只要if(n),n不为null,0,undefined数值,都会转换为true。进入console.info(a == true);最终返回false。
[]==[] A.true B.false C.报错 D.其余
数组,在 Javascript 中是对象,对象使用 == 比较都是比较的引用。简单的说,就是,若是是同一个对象,就相等,若是不是同一个对象,就不等。每次使用 [] 都是新建一个数组对象,因此 [] == [] 这个语句里建了两个数据对象,它们不等。
[('5'+3),('5'-3)] A.["53",2] B.[8,2] C.报错 D.其余
执行'5'+3,加号具有拼接字符串功能,会将3强制转换为字符串'3'和'5'拼接。
执行'5'-3,减号只具有数值运算的功能,所以会将'5'转化为数值,进行5-3的数值运算
1+-+++-+1 A.true B.false C.报错 D.其余
var arr = Array(3); arr[0] = 2 arr.map(function(elem){return '1';}); A.[2,1,1] B.["1","1","1"] C.[2,"1","1"] D.其余
区分赋值和声明。虽然var arr = Array(3);建立一个长度为3的数组,可是实际只有一个元素被赋值,所以arr的实际长度为1,即最终参与map的只有一个元素,返回[1]
function sidEffecting(arr){ arr[0] = arr[2]; } function bar(a,b,c){ c = 10; sidEffecting(arguments); return a+b+c; } bar(1,1,1); A.3 B.12 C.报错 D.其余
按照执行步骤,无需多疑,最终结果为10+1+10
var a = 111111111111111110000; b = 1111; console.info(a+b); A.111111111111111111111 B.111111111111111110000 C.NaN D.Infinity
js的精确整数最大为:Math.pow(2,53)-1 =9007199254740991.
var a = 111111111111111110000,
max = 9007199254740992;
a的值大于javascript所能表示的最大整数精度,所以和任何数值相加将会致使失真。
var x = [].reverse; x(); A.[] B.undefined C.报错 D.window
正确调用方式为x.call([])
Number.MIN_VALUE>0 A.true B.false C.报错 D.其余
Number.MIN_VALUE表示的最小值为5e-324,MIN_VALUE表明的并非负最小,而是最接近0的一个数,所以Number.MIN_VALUE>0。
负最小值可使用-Number.MAX_VALUE表示。
[1<2<3,3<2<1] A.[true,true] B.[true,false] C.报错 D.其余
1<2,返回true,执行true<3,会强制将true转换为1,1<3,最终返回true。
3<2,返回false,执行false<1,会强制将false转换为0,0<1,最终返回true。
2 == [[[2]]] A.true B.false C.undefined D.其余
使用a==b判断a和b对象是否相等,能够会将b对象强制转换为a对象的类型,即执行2 == [[[2]]],会隐式调用parseInt([[[2]]])将[[[2]]]强制转化为数字基本量,即2,2==2,最终返回true。
[3.toString(),3..toString(),3...toString()] A.["3",error,error] B.["3","3.0",error] C.[error,"3",error] D.其余
Number中的toString(a),可以将数值转化成为a进制的值。但a缺省时,默认转化为十进制。
通常使用方法为:var n = 3;3.toString();
执行3.toString(),由于3只是为数值型变量,为非Number实例,所以对于3不能直接调用Number方法。而执行3..toString(),会强制将3转化为数字实例,所以可以被解释,输出3,一样可使用(3).toString()。
(function(){ var x1 =y1 =1; })(); console.info(y1); console.info(x1); A.1,1 B.error,error C.1,error D.其余
在当即调用函数内执行,var x1 =y1 =1;建立局部变量x1和全局变量y1。函数外部试图访问函数内部的变量,将会致使错误。
(1)window.event 表示当前的事件对象,IE有这个对象,FF没有
(2)获取事件源 IE用srcElement获取事件源,而FF用target获取事件源
(3)添加、移除事件 IE:element.attachEvent("onclick",function) element.detachEvent("onclick",function) FF:element.addEventListener("click",function,true) element.removeEventListener("click",function,true)
function initButtons(){ var body = document.body,button,i; for(i =0;i<5;i++){ button = document.createElement("button"); button.innerHTML = "Button" + i; button.addEventListener("click",function(e){ alert(i); },false); body.appendChild(button); } } initButtons();
题目所给出的代码,除了有addEventListener不兼容IE浏览器的问题以外,最突出的一个问题是:
虽然在页面上会显示值为button+i的按钮,可是点击任意一个按钮,最终都会显示5。
要想点击相关按钮,弹出相应的1,2,3,4,5的值,须要理解闭包原理实现和使用当即回调函数。修改后的代码以下:
function initButtons(){ var body = document.body,button,i; for(i =0;i<5;i++){ (function(i){ button = document.createElement("button"); button.innerHTML = "Button" + i; button.addEventListener("click",function(e){ alert(i); },false); body.appendChild(button); })(i); } } initButtons();
涉及绑定和赋值获得区别。在运行时,进入一个做用域,javascript会为每个绑定到该做用域的变量在内存中分配一个“槽”(slot)。函数中,建立变量document.body,button,i,所以当函数体(建立按钮,并为按钮绑定事件)被调用时,函数会为每一个变量分配一个“槽”。在循环的每次迭代中,循环体都会为嵌套函数分配一个闭包。咱们可能理解为,该函数存储的是嵌套函数建立时变量i的值。但事实上,他存储的是i的引用。因为每次函数建立后变量i的值都发生变化,所以函数内部最终看到的是变量i的引用。闭包存储的是外部变量的引用而非值。
当即调用的函数表达式,是一种不可或缺的解决javascript缺乏块级做用域的方法。
须要深刻理解,能够查看《Effective JavaScript》第13条:使用当即调用的函数表达式建立局部做用域
判断一个字符串中出现次数最多的字符,并统计出现的次数。
使用常规方法和正则表达式匹配两种算法
/*写一段代码。判断一个字符串中出现次数最多的字符串,并统计出现的次数*/
function toGetTheMostCharsByArray(s){
var r={}; for(var i=0;i<s.length;i++){ if(!r[s[i]]){ r[s[i]] = 1; }else{ r[s[i]]++; } } var max = { "value " :s[0], "num" : r[s[0]] }; for(var n in r){//对象使用in关键字,由于没有length if(r[n]>max.num){ max.num = r[n]; max.value = n; } } return max; } function toGetTheMostCharsByRegex(s){ var a = s.split(''); a.sort(); s = a.join(''); var regex = /(\w)\1+/g ;//\1表明重复的 var max = { "value " :s[0], "num" : 0 }; s.replace(regex,function(a,b){ if(max.num < a.length){ max.num = a.length; max.value= b; } }); return max; } var test = "efdfssssfrhth"; console.info("使用常规方法 ,出现最多的字符串为:"+toGetTheMostCharsByArray(test).value+" ,出现次数:"+toGetTheMostCharsByArray(test).num); console.info("使用字符串匹配,出现最多的字符串为:"+toGetTheMostCharsByRegex(test).value+" ,出现次数:"+toGetTheMostCharsByRegex(test).num);
(1)setTimeout(function(){ /*代码块*/ setTimeout(arguments.callee,10); },10); (2)setInterval(function(){ /*代码块*/ },10);
javascript的引擎是单线程的
javascript的引擎是基于事件驱动的
setTimeout和setInterval都是往事件队列中增长一个待处理时间而已,setTimeout只触发一次,而setInterval是循环触发
setTimeout(function(){ //代码块 setTimeout(arguments.callee,10); },10);
上段代码可以使得setTimeout循环触发。可是,执行完这段代码块才挂起时间,因此两次执行时间会大于10毫秒
setInterval(function(){ /*代码块*/ },10);
而上段代码,是自动在10的时候挂上这个事件,因此两次事件的相隔会小于等于10毫秒。
当线程阻塞在一个事件的时候,无论是使用setInterval仍是setTimeout都须要等待当前事件处理完才能执行。
年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很惋惜到目前为止的将近两年中,几乎没有人可以彻底答对,并不是多难只是由于大多面试者过于轻视他。
题目以下:
function Foo() {
getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //请写出如下输出结果: Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName();
答案是:
function Foo() {
getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //答案: Foo.getName();//2 getName();//4 Foo().getName();//1 getName();//1 new Foo.getName();//2 new Foo().getName();//3 new new Foo().getName();//3
此题是我综合以前的开发经验以及遇到的JS各类坑聚集而成。此题涉及的知识点众多,包括变量定义提高、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等等。
此题包含7小问,分别说下。
先看此题的上半部分作了什么,首先定义了一个叫Foo的函数,以后为Foo建立了一个叫getName的静态属性存储了一个匿名函数,以后为Foo的原型对象新建立了一个叫getName的匿名函数。以后又经过函数变量表达式建立了一个getName的函数,最后再声明一个叫getName函数。
第一问的 Foo.getName 天然是访问Foo函数上存储的静态属性,天然是2,没什么可说的。
第二问,直接调用 getName 函数。既然是直接调用那么就是访问当前上文做用域内的叫getName的函数,因此跟1 2 3都没什么关系。此题有无数面试者回答为5。此处有两个坑,一是变量声明提高,二是函数表达式。
即全部声明变量或声明函数都会被提高到当前函数的顶部。
例以下代码:
console.log('x' in window);//true var x;
x = 0;
代码执行时js引擎会将声明语句提高至代码最上方,变为:
var x; console.log('x' in window);//true x = 0;
var getName 与 function getName 都是声明语句,区别在于 var getName 是函数表达式,而 function getName 是函数声明。关于JS中的各类函数建立方式能够看 大部分人都会作错的经典JS闭包面试题 这篇文章有详细说明。
函数表达式最大的问题,在于js会将此代码拆分为两行代码分别执行。
例以下代码:
console.log(x);//输出:function x(){} var x=1; function x(){}
实际执行的代码为,先将 var x=1 拆分为 var x; 和 x = 1; 两行,再将 var x; 和 function x(){} 两行提高至最上方变成:
var x; function x(){} console.log(x); x=1;
因此最终函数声明的x覆盖了变量声明的x,log输出为x函数。
同理,原题中代码最终执行时的是:
function Foo() {
getName = function () { alert (1); }; return this; } var getName;//只提高变量声明 function getName() { alert (5);}//提高函数声明,覆盖var的声明 Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; getName = function () { alert (4);};//最终的赋值再次覆盖function getName声明 getName();//最终输出4
第三问的 Foo().getName(); 先执行了Foo函数,而后调用Foo函数的返回值对象的getName属性函数。
Foo函数的第一句 getName = function () { alert (1); }; 是一句函数赋值语句,注意它没有var声明,因此先向当前Foo函数做用域内寻找getName变量,没有。再向当前函数做用域上层,即外层做用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为 function(){alert(1)}。
此处其实是将外层做用域内的getName函数修改了。
注意:此处若依然没有找到会一直向上查找到window对象,若window对象中也没有getName属性,就在window对象中建立一个getName变量。
以后Foo函数的返回值是this,而JS的this问题博客园中已经有很是多的文章介绍,这里再也不多说。
简单的讲,this的指向是由所在函数的调用方式决定的。而此处的直接调用方式,this指向window对象。
遂Foo函数返回的是window对象,至关于执行 window.getName() ,而window中的getName已经被修改成alert(1),因此最终会输出1
此处考察了两个知识点,一个是变量做用域问题,一个是this指向问题。
直接调用getName函数,至关于 window.getName() ,由于这个变量已经被Foo函数执行时修改了,遂结果与第三问相同,为1
第五问 new Foo.getName(); ,此处考察的是js的运算符优先级问题。
js运算符优先级:
参考连接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
经过查上表能够得知点(.)的优先级高于new操做,遂至关因而:
new (Foo.getName)();
因此实际上将getName函数做为了构造函数来执行,遂弹出2。
第六问 new Foo().getName() ,首先看运算符优先级括号高于new,实际执行为
(new Foo()).getName()
遂先执行Foo函数,而Foo此时做为构造函数却有返回值,因此这里须要说明下js中的构造函数返回值问题。
在传统语言中,构造函数不该该有返回值,实际执行的返回值就是此构造函数的实例化对象。
而在js中构造函数能够有返回值也能够没有。
一、没有返回值则按照其余语言同样返回实例化对象。
二、如有返回值则检查其返回值是否为引用类型。若是是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。
三、若返回值是引用类型,则实际返回值为这个引用类型。
原题中,返回的是this,而this在构造函数中原本就表明当前实例化对象,遂最终Foo函数返回实例化对象。
以后调用实例化对象的getName函数,由于在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了。
遂最终输出3。
第七问, new new Foo().getName(); 一样是运算符优先级问题。
最终实际执行为:
new ((new Foo()).getName)();
先初始化Foo的实例化对象,而后将其原型上的getName函数做为构造函数再次new。
遂最终结果为3
===2016年03月23日更新===
这里引用 @于明昊 的评论,更详细的解释了第7问:
这里确实是(new Foo()).getName(),可是跟括号优先级高于成员访问不要紧,实际上这里成员访问的优先级是最高的,所以先执行了 .getName,可是在进行左侧取值的时候, new Foo() 能够理解为两种运算:new 带参数(即 new Foo())和函数调用(即 先 Foo() 取值以后再 new),而 new 带参数的优先级是高于函数调用的,所以先执行了 new Foo(),或得 Foo 类的实例对象,再进行了成员访问 .getName。
就答题状况而言,第一问100%均可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就很少了,第四问再正确就很是很是少了。其实此题并无太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡是有1年到2年的工做经验都应该彻底正确才对。
只能说有一些人太急躁过轻视了,但愿你们经过此文了解js一些特性。
并祝愿你们在新的一年找工做面试中胆大心细,发挥出最好的水平,找到一份理想的工做。
高阶函数就是能够将函数做为另外一个函数的参数。
例如:将两个数的平方相加,这里匿名函数fn就是函数被做为参数。
function add(a,b,fn){ return fn(a)+fn(b); } var fn=function (a){ return a*a; } add(2,3,fn);
1.map做用在数组的每一个元素上的函数。
例如:将数组arr的每一个元素都加上10。
var arr=[5,6,7,8,9]; var fn=function(a){ return a+10; } console.log(arr.map(fn));
2.reduce也做用在数组上,可是每次只能接受两个参数。
例如:将数组arr的每一个元素相加,由于元素为字符串,因此链接在一块儿。
var arr=["小","明","喜","欢","学","习"]; var fn=function(a,b){ return a+b; } console.log(arr.reduce(fn));
也能够写成:
var arr=["小","明","喜","欢","学","习"]; function fn(arr){ return arr.reduce(function(a,b){ return a+b; }) } console.log(fn(arr));
3.filter用于过滤数组的元素。
例如:过滤掉arr内的偶数。
var arr=[1,2,3,4,5,6,7,8,9,10]; var fn=arr.filter(function(x){ return x%2!=0; }) console.log(fn);
4.sort用于将数组进行排序,此函数默认会将数组内的元素转换成字符串类型进行排序,且按照大写在前的规律排序。
var arr=["X","y","Z","A","b","C"]; console.log(arr.sort());
忽略大小写进行排序。
若是倒叙的话将1与-1的值交换。
function fn(a,b){ var a1=a.toLowerCase(); var b1=b.toLowerCase() if(a1>b1){ return -1; } if(a1<b1){ return 1; } return 0; } var newArr=arr.sort(fn); console.log(newArr);
固然也有一个倒叙的函数
console.log(newArr.reverse());
webSocket例子
[http://www.cnblogs.com/wei2yi/archive/2011/03/23/1992830.html]
是下一代客户端-服务器的异步通讯方法,该通讯取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序;并且有一个优秀的第三方API,名为Socket.IO
服务器和客户端能够在给定的时间范围内的任意时刻,相互推送信息;
与ajax的区别:
WebSocket并不限于以Ajax(或XHR)方式通讯,由于Ajax技术须要客户端发起请求,而WebSocket服务器和客户端能够彼此相互推送信息;XHR受到域的限制,而WebSocket容许跨域通讯
// 建立一个Socket实例 var socket = new WebSocket('ws://localhost:8080'); //ws表示socket协议 // 打开Socket socket.onopen = function(event) { // 发送一个初始化消息 socket.send('I am the client and I\'m listening!'); // 监听消息 socket.onmessage = function(event) { console.log('Client received a message',event); }; // 监听Socket的关闭 socket.onclose = function(event) { console.log('Client notified socket has closed',event); }; // 关闭Socket.... socket.close() };
(内容5)——————
HTML5 文档类型很简单:<!doctype html>
HTML5 使用 UTF-8 编码示例:
HTML5 支持 MP三、Wav 和 Ogg 格式的音频,下面是在网页中嵌入音频的简单示例:
<audio controls> <source src=”jamshed.mp3″ type=”audio/mpeg”> Your browser does’nt support audio embedding feature. </audio>
和音频相似,HTML5 支持 MP四、WebM 和 Ogg 格式的视频,下面是简单示例:
1
2
3
4
|
<video width=”450″ height=”340″ controls>
<source src=”jamshed.mp4″ type=”video/mp4″>
Your browser does’nt support video embedding feature.
</video>
|
HTML5的离线储存怎么使用,工做原理能不能解释一下?
在用户没有与因特网链接时,能够正常访问站点或应用,在用户与因特网链接时,更新用户机器上的缓存文件。 原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),经过这个文件上的解析清单离线存储资源,这些资源就会像cookie同样被存储了下来。以后当网络在处于离线状态下时,浏览器会经过被离线存储的数据进行页面展现。 如何使用: 一、页面头部像下面同样加入一个manifest的属性; 二、在cache.manifest文件的编写离线存储的资源; CACHE MANIFEST #v0.11 CACHE: js/app.js css/style.css NETWORK: resourse/logo.png FALLBACK: / /offline.html 三、在离线状态时,操做window.applicationCache进行需求实现。
详细的使用请参考:有趣的HTML5:离线存储
写一个通用的事件侦听器函数。
// event(事件)工具集,来源:github.com/markyun markyun.Event = { // 页面加载完成后 readyEvent : function(fn) { if (fn==null) { fn=document; } var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = fn; } else { window.onload = function() { oldonload(); fn(); }; } }, // 视能力分别使用dom0||dom2||IE方式 来绑定事件 // 参数: 操做的元素,事件名称 ,事件处理程序 addEvent : function(element, type, handler) { if (element.addEventListener) { //事件类型、须要执行的函数、是否捕捉 element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent('on' + type, function() { handler.call(element); }); } else { element['on' + type] = handler; } }, // 移除事件 removeEvent : function(element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.datachEvent) { element.detachEvent('on' + type, handler); } else { element['on' + type] = null; } }, // 阻止事件 (主要是事件冒泡,由于IE不支持事件捕获) stopPropagation : function(ev) { if (ev.stopPropagation) { ev.stopPropagation(); } else { ev.cancelBubble = true; } }, // 取消事件的默认行为 preventDefault : function(event) { if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } }, // 获取事件目标 getTarget : function(event) { return event.target || event.srcElement; }, // 获取event对象的引用,取到事件的全部信息,确保随时能使用event; getEvent : function(e) { var ev = e || window.event; if (!ev) { var c = this.getEvent.caller; while (c) { ev = c.arguments[0]; if (ev && Event == ev.constructor) { break; } c = c.caller; } } return ev; } };
什么是闭包(closure),为何要用它?
执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在.使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源,由于say667()的内部函数的执行须要依赖say667()中的变量。这是对闭包做用的很是直白的描述. function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; } var sayAlert = say667(); sayAlert()//执行结果应该弹出的667
模块化怎么作?
当即执行函数,不暴露私有成员
var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })();
.call() 和 .apply() 的区别?
例子中用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,因此运行结果为:alert(4); 注意:js 中的函数实际上是对象,函数名是对 Function 对象的引用。 function add(a,b) { alert(a+b); } function sub(a,b) { alert(a-b); } add.call(sub,3,1);
用jQuery实现数组转字符串
jQuery中没有提供这个功能,因此你须要先编写两个jQuery的扩展:
$.fn.stringifyArray = function(array) { return JSON.stringify(array) } $.fn.parseArray = function(array) { return JSON.parse(array) } 而后调用: $("").stringifyArray(array)
针对 jQuery 的优化方法?
*基于Class的选择性的性能相对于Id选择器开销很大,由于需遍历全部DOM元素。 *频繁操做的DOM,先缓存起来再操做。用Jquery的链式调用更好。 好比:var str=$("a").attr("href"); *for (var i = size; i < arr.length; i++) {} for 循环每一次循环都查找了数组 (arr) 的.length 属性,在开始循环的时候设置一个变量来存储这个数字,可让循环跑得更快: for (var i = size, length = arr.length; i < length; i++) {}