【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

时间:2021-02-23 21:14:46

编写一个方法 求一个字符串的字节长度
假设:一个英文字符占用一个字节,一个中文字符占用两个字节

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)进行值复制

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.冒泡排序、快速排序、去重、查找字符串最多值

//冒泡排序
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继承

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.事件绑定

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.浅克隆和深度克隆

//浅克隆
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.实现一个秒针绕一点转动的效果

  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之间的随机数,存在数组中,常见排序方法,数组乱序方法

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)

运行效果
【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
 
3. 纯js实现
需要求一个点在不在圆上简单算法、获取鼠标坐标等等
两点之间的距离计算公式  

上面公式对于JavaScript代码如下:

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

|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("外")
}
}

WEB前端 | H5基础——(4)流式布局、响应式布局、Viewport

一 、流式布局

<!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、弹性图片(给宽度,高度会自适应,不失真)
4、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>

二、响应式布局

<!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>
三、Viewport
<!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>
 

5个经典的前端面试问题,你行吗?

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;
}

11、如何深度克隆
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

2017.8.31收集

JavaScript-有意思的30题_题目

来源:温故js系列(13.2)-有意思的30题_解析

之前在学习时把问题和答案分开了,这儿也分开吧。这样在看得时候无意识的会多思考一下。茶余饭后,来杯咖啡

1.以下表达式的运行结果是:

["1","2","3"].map(parseInt)
A.["1","2","3"]
B.[1,2,3]
C.[0,1,2]
D.其他

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]。

2.以下表达式的运行结果是:

[typeof null, null instanceof Object]
A.["object",false]
B.[null,false]
C.["object",true]
D.其他

A

typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:

number,boolean,string,function(函数),object(NULL,数组,对象),undefined

instanceof 表示某个变量是否是某个对象的实例,null是个特殊的Object类型的值 ,表示空引用的意思 。但null返回object这个其实是最初JavaScript的实现的一个错误, 
然后被ECMAScript沿用了,成为了现在的标准,不过我们把null可以理解为尚未存在的对象的占位符,这样就不矛盾了 ,虽然这是一种“辩解”。
对于我们开发人员 还是要警惕这种“语言特性”。最终返回:["object", false]

3.以下表达式的运行结果是:

[[3,2,1].reduce(Math.pow),[].reduce(Math.pow)]
A.报错
B.[9,0]
C.[9,NaN]
D.[9,undefined]

A

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();会导致错误。

4.以下表达式的运行结果是:

var val = 'value';
console.info('Value id '+(val === 'value')?'Something':'Nothing');
A.Something
B.Nothing
C.NaN
D.其他

A

先执行字符串拼接,再执行校验

var val = 'value';
console.info('Value id '+(val === 'value123')?'Something':'Nothing');

同样会返回something

5.以下表达式的运行结果是:

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

A

判断语句被包裹在立即调用函数里,函数内部无法访问外部值为'World'的name,因此typeof name === 'undefined'为真,执行下一步操作,最终输出Goodbye Jack

6.以下表达式的运行结果是:

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.其他

D

END = 9007199254740992 ,START = 9007199254740892目的是计算的END和START之间的差。但是2的53次方计算出的结果由于精度问题使得i++失效。

7.以下表达式的运行结果是:

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]

C

filter会接触到没有被赋值的元素,即在arr中,长度为10但实际数值元素列表为[0, 1, 2, 10],因此,最终返回一个空的数组[]。

8.以下表达式的运行结果是:

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.其他

C

两个浮点数相加或者相减,将会导致一定的正常的数据转换造成的精度丢失问题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)

9.以下表达式的运行结果是:

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

C

使用new String()使用构造函数调用讲一个全新的对象作为this变量的值,并且隐式返回这个新对象作为调用的结果,因此showCase()接收的参数为String {0: "A"}为不是我们所认为的“A”

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(String('A'));
A.Case A
B.Case B
C.Do not know
D.undefined

A

直接调用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,成员的属性

11.以下表达式的运行结果是:

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]

C

function isSane(num){
return isEven(num)||isOdd(num);
}

该函数判断num是否为正整数,'13'被强制转换为数值13,-9%2结果为-1,Infinity %2为NaN

12.以下表达式的运行结果是:

[parseInt(3,8),parseInt(3,2),parseInt(3,0)]
A.[3,3,3]
B.[3,3,NaN]
C.[3,NaN,NaN]
D.其他

D

最终结果为[3, NaN, 3];
parseInt() 函数可解析一个字符串,并返回一个整数。当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。

13.以下表达式的运行结果是:

 

Array.isArray(Array.prototype)
A.true
B.false
C.报错
D.其他

A

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

14.以下表达式的运行结果是:

var a = [0];
if([0]){
console.info(a == true);
}else{
console.info("false");
}
A.true
B.false
C."else"
D.其他

B

在if条件判断语句相对于==比较宽松中,只要if(n),n不为null,0,undefined数值,都会转换为true。进入console.info(a == true);最终返回false。

15.以下表达式的运行结果是:

[]==[]
A.true
B.false
C.报错
D.其他

B

数组,在 Javascript 中是对象,对象使用 == 比较都是比较的引用。简单的说,就是,如果是同一个对象,就相等,如果不是同一个对象,就不等。每次使用 [] 都是新建一个数组对象,所以 [] == [] 这个语句里建了两个数据对象,它们不等。

16.以下表达式的运行结果是:

[('5'+3),('5'-3)]
A.["53",2]
B.[8,2]
C.报错
D.其他

A

执行'5'+3,加号具备拼接字符串功能,会将3强制转换为字符串'3'和'5'拼接。
执行'5'-3,减号只具备数值运算的功能,因此会将'5'转化为数值,进行5-3的数值运算

17.以下表达式的运行结果是:

1+-+++-+1
A.true
B.false
C.报错
D.其他

C

18.以下表达式的运行结果是:

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.其他

D

区分赋值和声明。虽然var arr = Array(3);创建一个长度为3的数组,但是实际只有一个元素被赋值,因此arr的实际长度为1,即最终参与map的只有一个元素,返回[1]

19.以下表达式的运行结果是:

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.其他

D

按照执行步骤,无需多疑,最终结果为10+1+10

20.以下表达式的运行结果是:

var a = 111111111111111110000;
b = 1111;
console.info(a+b);
A.111111111111111111111
B.111111111111111110000
C.NaN
D.Infinity

B

js的精确整数最大为:Math.pow(2,53)-1 =9007199254740991.
var a = 111111111111111110000,
max = 9007199254740992;
a的值大于javascript所能表示的最大整数精度,因此和任何数值相加将会导致失真。

21.以下表达式的运行结果是:

var x = [].reverse;
x();
A.[]
B.undefined
C.报错
D.window

C

正确调用方式为x.call([])

22.以下表达式的运行结果是:

Number.MIN_VALUE>0
A.true
B.false
C.报错
D.其他

A

Number.MIN_VALUE表示的最小值为5e-324,MIN_VALUE代表的并不是负最小,而是最接近0的一个数,因此Number.MIN_VALUE>0。
负最小值可以使用-Number.MAX_VALUE表示。

23.以下表达式的运行结果是:

[1<2<3,3<2<1]
A.[true,true]
B.[true,false]
C.报错
D.其他

A

1<2,返回true,执行true<3,会强制将true转换为1,1<3,最终返回true。
3<2,返回false,执行false<1,会强制将false转换为0,0<1,最终返回true。

24.以下表达式的运行结果是:

2 == [[[2]]]
A.true
B.false
C.undefined
D.其他

A

使用a==b判断a和b对象是否相等,可以会将b对象强制转换为a对象的类型,即执行2 == [[[2]]],会隐式调用parseInt([[[2]]])将[[[2]]]强制转化为数字基本量,即2,2==2,最终返回true。

25.以下表达式的运行结果是:

[3.toString(),3..toString(),3...toString()]
A.["3",error,error]
B.["3","3.0",error]
C.[error,"3",error]
D.其他

C

Number中的toString(a),能够将数值转化成为a进制的值。但a缺省时,默认转化为十进制。
一般使用方法为:var n = 3;3.toString();
执行3.toString(),因为3只是为数值型变量,为非Number实例,因此对于3不能直接调用Number方法。而执行3..toString(),会强制将3转化为数字实例,因此能够被解释,输出3,同样可以使用(3).toString()。

26.以下表达式的运行结果是:

(function(){
var x1 =y1 =1;
})();
console.info(y1);
console.info(x1);
A.1,1
B.error,error
C.1,error
D.其他

C

在立即调用函数内执行,var x1 =y1 =1;创建局部变量x1和全局变量y1。函数外部试图访问函数内部的变量,将会导致错误。

27.列举IE和FF脚本兼容性的问题列举IE和FF脚本兼容性的问题

(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)

28.以下函数有什么问题?如何改进?

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条:使用立即调用的函数表达式创建局部作用域

29.写一段代码

判断一个字符串中出现次数最多的字符,并统计出现的次数。

使用常规方法和正则表达式匹配两种算法

/*写一段代码。判断一个字符串中出现次数最多的字符串,并统计出现的次数*/

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);

30.请问一下两段代码有什么不同?

(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都需要等待当前事件处理完才能执行。

原文链接:一道常被人轻视的前端JS面试题

年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套前端面试题中的最后一题,用来考核面试者的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运算符优先级:

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

参考链接: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中构造函数可以有返回值也可以没有。

1、没有返回值则按照其他语言一样返回实例化对象。

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

2、若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

3、若返回值是引用类型,则实际返回值为这个引用类型。

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题

原题中,返回的是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一些特性。

并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。

来源:javascript小记一笔——(高阶函数、map、reduce、filter、sort、reverse)

高阶函数就是可以将函数作为另一个函数的参数。
例如:将两个数的平方相加,这里匿名函数fn就是函数被作为参数。

function add(a,b,fn){
return fn(a)+fn(b);
}
var fn=function (a){
return a*a;
}
add(2,3,fn);

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
1.map作用在数组的每个元素上的函数。
例如:将数组arr的每个元素都加上10。

var arr=[5,6,7,8,9];
var fn=function(a){
return a+10;
}
console.log(arr.map(fn));

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
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));

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
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);

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
4.sort用于将数组进行排序,此函数默认会将数组内的元素转换成字符串类型进行排序,且按照大写在前的规律排序。

var arr=["X","y","Z","A","b","C"];
console.log(arr.sort());

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
忽略大小写进行排序。

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题如果倒叙的话将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);

【编码题篇】收集整理来自网络上的一些常见的 经典前端、H5面试题 Web前端开发面试题
当然也有一个倒叙的函数

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)——————

10个最常见的 HTML5 面试题及答案

1、新的 HTML5 文档类型和字符集是?

HTML5 文档类型很简单:<!doctype html>

HTML5 使用 UTF-8 编码示例:

<meta charset=”UTF-8″>

2、HTML5 中如何嵌入音频?

HTML5 支持 MP3、Wav 和 Ogg 格式的音频,下面是在网页中嵌入音频的简单示例:

<audio controls>
<source src=”jamshed.mp3″ type=”audio/mpeg”>
Your browser does’nt support audio embedding feature.
</audio>

3、HTML5 中如何嵌入视频?

和音频类似,HTML5 支持 MP4、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>

更新时间: 2015-10-9

HTML

HTML5的离线储存怎么使用,工作原理能不能解释一下?

在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。
原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。 如何使用:
1、页面头部像下面一样加入一个manifest的属性;
2、在cache.manifest文件的编写离线存储的资源;
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/ /offline.html
3、在离线状态时,操作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++) {}