JS篇
1.问:js中"1"+2+"3"+4 运算结果是?
答:1234
js中,字符串和数值相加,得到的还是字符串,这里的结果1234也是字符串。
2.问:4+3+2+"1" 运算结果是?
答:91 (从左至右的运算,前面是数值相加得到9,再和字符串相加得到91字符串。)
3.问:以下代码中,结果是?
var foo = 1; function bar() { foo = 10; return; function foo() {} } bar(); alert(foo);
答:将输出1. (这里访问的是window.foo,而不是bar里面的foo)
解析:
http://www.zhihu.com/question/29610784?sort=created https://segmentfault.com/q/1010000000598752 先分析一下每步流程: 第一步:var foo = 1; 全局变量foo被初始化赋值成1。 第二步:执行bar();方法。 第三步:bar()方法里,函数声明function foo(){}优先处理,这里JavaScript解析语法时(在运行之前)函数优先于一切。所以foo被初始化赋值为function(){}; 第四步:执行foo = 10;这里制造了一个假象,认为没有用var 声明指向的是外层foo = 1;。其实不是。而是先在自身函数体里找有没有foo声明,找到之前声明的function foo(){};赋值成10,只是局部变量的值改写。 第五步:输出foo,这时找的是全局变量var foo = 1;输出1。 等于说在bar中,foo其实指向的是function foo(){},而不是外面的foo。
4.问:以下代码中,结果是?
function bar() { return foo; foo = 10; function foo() {} var foo = 11; } alert(typeof bar());
前端开发面试题收集(js部分)
1.问:js中"1"+2+"3"+4 运算结果是?
答:1234
js中,字符串和数值相加,得到的还是字符串,这里的结果1234也是字符串。
2.问:4+3+2+"1" 运算结果是?
答:91 (从左至右的运算,前面是数值相加得到9,再和字符串相加得到91字符串。)
3.问:以下代码中,结果是?
答:将输出1. (这里访问的是window.foo,而不是bar里面的foo)
4.问:以下代码中,结果是?
function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = 11;
}
alert(typeof bar());
答:将输出function.
5.问:以下代码中,结果是?
var x = 3; var foo = { x: 2, baz: { x: 1, bar: function() { return this.x; } } } var go = foo.baz.bar; alert(go()); alert(foo.baz.bar());
6.问:以下代码中,结果是?
var x = 4, obj = { x: 3, bar: function() { var x = 2; setTimeout(function() { var x = 1; alert(this.x); }, 1000); } }; obj.bar();
答:输出4.
setTimeout方法是挂在window对象下的。setTimeout(匿名函数,time),这里的匿名函数形成了一个闭包,从而能访问到外层函数的局部变量。也就是window中的x。(参考)
7.问:以下代码中,结果是?
x = 1; function bar() { this.x = 2; return x; } var foo = new bar(); alert(foo.x);
答:输出2.
这里的this指向的是bar的对象实例。
8.问:以下代码中,结果是?
function foo(a) { alert(arguments.length); } foo(1, 2, 3);
答:3.
9.问:以下代码中,结果是?
var foo = function bar() {}; alert(typeof bar);
答:function(答案是undefined,我觉得不对,而且尝试输出后也是function)
10.问:以下代码中,结果是?
var arr = []; arr[0] = 'a'; arr[1] = 'b'; arr.foo = 'c'; alert(arr.length);
答:2, 输出arr的值是["a", "b"]
11.问:以下代码中,结果是?
function foo(a) { arguments[0] = 2; alert(a); } foo(1);
2
12.问:以下代码中,结果是?
function foo(){} delete foo.length; alert(typeof foo.length);
答:number;foo.length的值还是0。
13.问:以下代码中,
var name="the window"; var object={ name:"my object", getName: function(){ return this.name; } }
通过以下调用
object.getName(); (object.getName)(); (object.getName = object.getName)()

第一行的代码,this指向的就是object,所以毫无疑问;第二行代码虽然加上括号,就好像只是在引用一个函数,但this的值得到了维持。因为object.getName和(object.getName)的定义相同。第三行代码,先执行一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以this的值不能得到维持,结果就返回the window.
http://www.kuqin.com/shuoit/20160629/352529.html
面试的时候并不建议使用白板,通常希望面试者自己带上自己的笔记本,或者就使用自己的。我会将他们的代码运行,并告知结果。
Object prototype
我起初会提出一个非常简单的问题就是定义一个函数spacify,将一个字符串作为参数传入,然后返回一个字符串,不过该字符串相对原有传入参数的变化是字母与字母之间多了一个空格。
spacify('hello world') // => 'h e l l o  w o r l d'   虽然问题很简单,但这却是一个很好的开始,我们接下来的问题便可以围绕此展开, 尤其对于那些声称自己了解Javascript,但实际却连一个函数都不会写的面试者高下立判。
正确的答案如下,不过一些面试者或许会选择for循环,当然这并没有错
function spacify(str) {     return str.split('').join(' '); } 接下来,我会继续问如何将这个函数直接作用在一个字符串对象上.
'hello world'.spacify();   这个问题可以让我了解面试者对原型链的理解,这个问题可以让彼此展开一些有讨论,诸如直接在原型链上定义属性的危害等等.实际期待结果:
String.prototype.spacify = function(){     return this.split('').join(' '); }; 一般到这里我会让面试者讲讲函数声明和函数表达式的区别。
Arguments
接下来,我会去了解面试者对于 arguments的理解,我们会要求面试者定一个log函数。
log('hello world');   函数类似实现一个简单的控制台输出,在控制台输出传入的字符串。一边面试者都会在定义的函数里直接写console.log,不过还是有更优秀的面试者会直接使用apply。
function log(msg){     console.log(msg); } 接下来,我会继续问如果我传入多个参数依旧输出一个字符串 ,我会提示面试者传入的 参数是不固定的,我会暗示作者console.log实际上也接受多个参数。
log('hello', 'world');   不过我还是希望您的面试者现在已经想起apply;面试者可能会在apply和call上困惑,这个时候我会做点小提示,不过将console上下文传入也是非常重要的.
function log(){     console.log.apply(console, arguments); }; 接着我会继续追问,如果我希望在那个输出的字符串前统一加上(app)这样的字符串,类似于这样:
'(app) hello world'   这个问题明显会复杂很多,面试者应该知道arguments是一个伪数组,我们需要先将它转换成正常的数组,我们可以使用Array.prototype.slice,代码如下:
function log(){     var args = Array.prototype.slice.call(arguments);   args.unshift('(app)');    console.log.apply(console, args); }; Context
接下来我想了解面试者对于上下文以及this的理解,我会给出下边的代码,让面试者去解释count的值。
var User = {     count: 1,    getCount: function() {     return this.count;   } }; 接下来我会给出下面的代码,让面试者去回答应该输出的正确答案。
console.log(User.getCount());  var func = User.getCount;   console.log(func());   上面的例子中正确输出1和undefined。实际上很多面试者都会在这里跌倒。func的上下文是 `window,因此已经失去了count属性。接下来我回继续追问面试者如何确保func的上下文始终都和User关联,这样可以使输出的答案是1。
正确答案是使用Function.prototype.bind,代码如下:
var func = User.getCount.bind(User);   console.log(func());   这个时候我会让面试者去进行完善,如果老的浏览器并不支持该方法,我们应该怎样去兼容。部分基础较差的面试者会比较纠结,但是个人认为任何一位前端工程师都应该对apply和call有着较为深刻的理解。
Function.prototype.bind = Function.prototype.bind || function(context) {       var self = this;      return function(){         return self.apply(context,   arguments);   }; } Extra points if the candidate shims bind so that it uses the browser's native version if available. At this point, if the candidate is doing really well, I'll ask them to implement currying arguments.
一个弹窗库
面试的最后y一部分,我会要求面试者写点实际的东西。这个非常有用,足以了解前端的技术栈。如果前面的问题回答的较为理想,这个问题,我会非常迅速的展开最后一个问题的考察。
虽然最终效果取决于面试者的实现,但是这里依旧有足够的考察点。
最好不使用position:absolute而是position:fixed,这个时候即使窗体有滚动,也可以很好的遮罩住全局。我会提示面试者这样使用,并且追问这两者的区别。
.overlay {   position: fixed;   left: 0;   right: 0;   bottom: 0;   top: 0;   background: rgba(0,0,0,.8); } 如何将里面的内容居中也是一个非常重要的考察点。一些面试者会使用绝对定位,而有的面试者则更擅长使用Js。
.overlay article {   position: absolute;   left: 50%;   top: 50%;   margin: -200px 0 0 -200px;   width: 400px;   height: 400px; } 我会继续问,如何确保点击遮罩层时遮罩层是关闭的?这个问题可以将我们的讨论落脚到 冒泡中来。很多面试者都会直接将点击实践绑定到遮罩层上。
$('.overlay').click(closeOverlay); 这个接下来可以工作了,但是你会发现如果点击了遮罩层中的子元素,遮罩层也会关闭。解决方案是便是判断event target ,并且保证 这个时间不会冒泡。
$('.overlay').click(function(e){   if (e.target == e.currentTarget)     closeOverlay(); }); 尾声
当然前面的知识点仅仅是前端的一部分,实际上你还可以问:性能,HTML5 APIs, AMD vs CommonJS modules,constructors,数据类型,以及盒子模型。我经常都会随着面试者的进行去选择相应的问题。
最后推荐大家都可以去看下Front-end-Developer-Interview-Questions以及JavaScript Garden.


 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号