有哪些经典的 Web 前端或者 JavaScript web前端面试笔试题题

年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多难只是因为大多面试者过于轻视他。
题目如下:
function Foo() {
getName = function () { alert (1); };
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); };
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
代码执行时js引擎会将声明语句提升至代码最上方,变为:
console.log('x' in window);//true
函数表达式
var getName 与 function getName 都是声明语句,区别在于 var getName 是函数表达式,而 function getName 是函数声明。关于JS中的各种函数创建方式可以看
这篇文章有详细说明。
函数表达式最大的问题,在于js会将此代码拆分为两行代码分别执行。
例如下代码:
console.log(x);//输出:function x(){}
function x(){}
实际执行的代码为,先将 var x=1 拆分为 和 x = 1; 两行,再将 和 function x(){} 两行提升至最上方变成:
function x(){}
console.log(x);
所以最终函数声明的x覆盖了变量声明的x,log输出为x函数。
同理,原题中代码最终执行时的是:
function Foo() {
getName = function () { alert (1); };
var getN//只提升变量声明
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运算符优先级:
参考链接:
通过查上表可以得知点(.)的优先级高于new操作,遂相当于是:
new (Foo.getName)();
所以实际上将getName函数作为了构造函数来执行,遂弹出2。
第六问 new Foo().getName() ,首先看运算符优先级括号高于new,实际执行为
(new Foo()).getName()
遂先执行Foo函数,而Foo此时作为构造函数却有返回值,所以这里需要说明下js中的构造函数返回值问题。
构造函数的返回值
在传统语言中,构造函数不应该有返回值,实际执行的返回值就是此构造函数的实例化对象。
而在js中构造函数可以有返回值也可以没有。
1、没有返回值则按照其他语言一样返回实例化对象。
2、若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。
3、若返回值是引用类型,则实际返回值为这个引用类型。
原题中,返回的是this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。
之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了。
遂最终输出3。
第七问, new new Foo().getName(); 同样是运算符优先级问题。
最终实际执行为:
new ((new Foo()).getName)();
先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new。
遂最终结果为3
就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。
只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。
并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。
在文章中找不到问题答案?您还可以
热门栏目订阅(经典)前端开发面试题答案&js篇
[Javascript]
1:js是什么,js和html
的开发如何结合?
2.怎样添加、移除、移动、复制、创建和查找节点
3.怎样使用事件以及IE和DOM事件模型之间存在哪些主要差别
4.面向对象编程:b怎么继承a
5.看看下面alert的结果是什么
view sourceprint?1.function b(x, y, a) {
.arguments[2] = 10;
.alert(a);
b(1, 2, 3);
如果函数体改成下面,结果又会是什么?
alert(arguments[2] );
6.请编写一个JavaScript函数 parseQueryString,
它的用途是把URL参数解析为一个对象
var obj = parseQueryString(url);
alert(obj.key0) // 输出0
7.ajax是什么? ajax的交互模型? 同步和异步的区别? 如何解决跨域问题?
ajax(动态网站静态化)伴随的goole
的推动,越来越多的站点开始使用了,在开大ajax(动态网站静态化)
程序的时候会遇到很多的问题,主要有以下几个方面:
1.跨浏览器问题
2.历史后退状态问题
3.跨域问题
跨浏览器的问题因为现在有很多的开元的框架已经解决了,我们无需为此而烦恼。
历史后退状态问题我们可以使用一个数组来保存历史纪录,然后把这些数据村到历史对象中去,
中的也可以解决,并且还有很多的开元框架给与支持,这样问题就不是很大。
跨域的问题就不是很好的解决,但是还是有办法的,一下给出一些基本的解决方案供大家选择:
1.使用代理,你可以使用web端的程序编写代理程序,把所有的ajax(动态网站静态化)请求的数据进行转发,
web程序可以使php(做为现在的主流
开发语言),jsp(SUN企业级应用的首选),asp等所有的编程语言。
相信大家对这种方式一定很熟悉,这里就不详细的介绍了。
2.使用iframe的方式来定势的刷新叶面,这种方式只是取得数据来显示,
并不能真正的和求得的数据进行交互,转化成本页面的动态数据,
不是很可取,应用也不是很多,我也忽略不去讨论了。
3.使用apache(Unix平台最流行的WEB服务器平台)的代理功能,
主要就是apache(Unix平台最流行的WEB服务器平台)的方向代理,
或者是url从定向,你也可以把其他的站点直接的挂在自己的网站上,
这样的方式可能会友邦权的问题,多的九部介绍了,有兴趣的本有可以自己实践以下。
4.使用《script》标签的方式,这样的话就可以保正使用真正的ajax(动态网站静态化)
来跨域,并且可以使用返回来的数据,发誓很简单,在我们的后台程序处理后的到的结果都直接的用javascript&
的方式返回,在我们的html中直接的使用返回数据的变量就可以了一个简单的例子
8.什么是闭包?下面这个ul,如何点击每一列的时候alert其index?
这是第一条
这是第二条
这是第三条
9.最近看的一篇Javas
cript的文章是?
10.常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?
pageSpeed .Yslow,Fiddler、fireBug
11.说说YSlow(可以详细一点)
这个插件可以分析网站的页面,并告诉你为了提高网站性能,
如何基于某些规则而进行优化。 网页制作方向的题目
1.什么是网站重构?div+css的布局较table布局有什么优点?
2.如何理解css盒模型?
3.平时做网页经常使用哪些hack?
4.如何理解表现与内容相分离?
5.如何解决ie6的双边距问题?
6. 如何定义高度为1px的容器?{heigh:1 width:10
background:#000;&
overflow:hidden}ie6下这个问题是默认行高造成的,overflow:hidden | zoom:0.08 |
line- height:1px这样也可以解决
7.如何实现一个层在浏览器中垂直左右居中?margin:auto
8.如何解决ie6的3像素问题?_zoom:1; margin-left: _margin-left:
9.为什么FF下文本无法撑开容器的高度?如何解决? 清楚浮动
10. 怎么样才能让层显示在FLASH之上呢? 解决的办法是给FLASH设置透明属性
1、 答:把"未采用CSS,大量使用HTML进行定位、布局,
或者虽然已经采用CSS,但是未遵循HTML结构化标准的站点"变成"让标记回归标记的原本意&
义。通过在HTML文档中使用结构化的标记以及用CSS控制页面表现,
使页面的实际内容与它们呈现的格式相分离的站点。"的过程就是网站重构
网站为什么要进行重构(网站重构的好处)
a、使页面加载得更快速;
b、降低带宽带来的费用:节约成本;
c、让你在修改设计时更有效率而代价更低;
d、帮助你的整个站点保持视觉的一致性;
e、更利于搜索引擎的检索(符合SEO的规范);
f、令站点更容易被各种浏览器和用户访问
(包括手机、PDA和残障人士使用的文字浏览器);
g、兼容不容忽视的Mozilla系浏览器(Firefox份额);
h、提高你的职场竞争实力(事实上也就是降低失业的风险)。
div+css的布局较table布局有什么优点:
1、改版的时候更方便 只要改css文件。2、页面加载速度更快、
结构化清晰、页面显示简洁。3、表现与结构相分离。
4、易于优化(seo)搜索引擎更友好,排名更容易靠前。
答:2.如何理解css盒模型 : 每个HTML元素都是长方形盒子 外边局(margin)、
内边距(padding)、边框(border); 答:3.平时做网页用的css
Ie6 * _; ie7 *, *+,! ff !important.
答:4.表现与结构相分离简单的说就是HTML中只有标签元素 表现完全是由CSS文件控制的
答:5.解决ie6双边距问题块级元素就加display:inline;
行内元素转块级元素display:inline后面再加display:table
6.如何定义高度为1px的容器?
{heigh:1 width:10 background:#000;
overflow:hidden}
ie6下这个问题是默认行高造成的,overflow:hidden | zoom:0.08 |
line-height:1px这样也可以解决
7.如何实现一个层在 浏览器中垂直左右居中?
margin:auto
8.如何解决ie6的3像素 问题?
_zoom:1; margin-left: _margin-left:
9.为什么FF下文本无法撑开容器的高度?如何解决?
清除浮动 .clear{ clear: height:0
overflow:}
10.怎么样才能让层显示在FLASH之上呢?&
解决的办法是给FLASH设置透明属性
补充: 1、margin-left:10px在FF和IE6下显示问题。IE6显示
20px,FF显示10px。
用!important就可以解决了。margin-left:10px
!margin-left:5
2、cursor:hand在FF不显示小手,如何解决?
3、要求在FF显示height为20IE6下显示height为25IE7下显示height为30px.
#test{height:20}
*html #test{height:25}
*+html #test{height:30}
这个以前我们说过,请参考【IE6的疯狂Bug之九】解决CSS兼容性最常用的"Haker"
三个就写上,FF只认识第一个#test,IE6只认识第二个*html #test,IE7只认识第三个*+html
PS:DTD必须加上要不还是不认。
4、在IE中内容会自适应高度,而FF不会自适应高度。
在要自适应高度的层中加一个层,样式为
.clear{clear:font-size:0height:1px},
这样解决有一个小小的问题,高度会多一个像素。
还有一种解决方法,给当前层加上一个伪类
#test:after {content: "."; display:
height: 0; clear: visibility:}
1.超链接访问过后hover样式就不出现的问题?
被点击访问过的超链接样式不在具有hover和active了,解决方法是改变CSS属性的排列顺序:
2.IE6的双倍边距BUG
body {margin:0} div { float: margin-left:10 width:200
height:200 border:1px solid red }
浮动后本来外边距10px,但IE解释为20px,解决办法是加上display:inline
3.为什么FF下文本无法撑开容器的高度?
标准浏览器中固定高度值的容器是不会象IE6里那样被撑开的,那我又想固定高度,
又想能被撑开需要怎样设置呢?办法就是去掉he ight设置min-height:200
这里为了照顾不认识min-height的IE6 可以这样定义:
div { height:auto! height:200 min-height:200
4.为什么web标准中IE无法设置滚动条颜色了?
原来样式设置:
body { scrollbar-face-color:#f6f6f6;
scrollbar-highlight-color:# scrollbar-shadow-color:#
scrollbar-3dlight-color:# scrollbar-arrow-color:#000;
scrollbar-track-color:# scrollbar-darkshadow-color:#
解决办法是将body换成html
5.为什么无法定义1px左右高度的容器?
IE6下这个问题是因为默认的行高造成的,
解决的方法也有很多,例如:overflow:hidden | zoom:0.08 | line-height:1px
6.怎么样才能让层显示在FLASH之上呢?
解决的办法是给FLASH设置透明:
7.怎样使一个层垂直居中于浏览器中?
div { position: top:50%; left:50%; margin:-100px 0 0
-100 width:200 height:200 border:1 }
这里使用百分比绝对定位,与外补丁负值的方法,
负值的大小为其自身宽度高度除以二
8、firefox嵌套div标签的居中问题的解决方法
假定有如下情况:
如果要实现b在a中居中放置,一般只需用CSS设置a的text-
align属性为center。这样的方法在IE里看起来一切正常;但是在Firefox中b却会是居左的。
解决办法就是设置b的横向margin为auto。例如设置b的CSS样式为:margin: 0。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 2016web前端笔试题 的文章

 

随机推荐