五个典型的javascript面试题
MiquelGuthr
8年前
<p>在IT界,需要大量的javascript开发者。如果这个角色能够最佳地展现你的能力,那么你有许多机会换家公司,以及提高薪水。但是在你被公司录取之前,你需要展现你的技术,以便通过面试环节。在这篇文章中,我会展示你五个典型的问题。</p> <h2>问题1: 范围(Scope)</h2> <p>思考以下代码:</p> <pre> <code class="language-javascript">(function() { var a = b = 5; })(); console.log(b);</code></pre> <p>控制台(console)会打印出什么?</p> <h3>答案</h3> <p>上述代码会打印出 5 。</p> <p>这个问题的陷阱就是,在立即执行函数表达式(IIFE)中,有两个命名,但是其中变量是通过关键词 var 来声明的。这就意味着 a 是这个函数的本地变量。与此相反, b 是属于这个函数的全局变量的。</p> <p>这个问题另一个陷阱就是,在函数中他没有使用 <em>"严格模式"</em> ( 'use strict'; )。如果 <a href="/misc/goto?guid=4959630741125305083" rel="nofollow,noindex">严格模式</a> 开启,那么代码就会报出未捕获引用错误(Uncaught ReferenceError):b没有定义。记住严格模式要求,如果这个是预期的行为,你需要明确地引用全局变量,。因此,你需要像下面这么写:</p> <pre> <code class="language-javascript">(function() { 'use strict'; var a = window.b = 5; })(); console.log(b);</code></pre> <h2>问题2: 创建 “原生(native)” 方法</h2> <p>在 String 对象上定义一个 repeatify 函数。这个函数接受一个整数参数,来明确字符串需要重复几次。这个函数要求字符串重复指定的次数。举个例子:</p> <pre> <code class="language-javascript">`console.log('hello'.repeatify(3));``</code></pre> <p>应该打印出 hellohellohello .</p> <h3>答案</h3> <p>一种可能的实现如下所示:</p> <pre> <code class="language-javascript">String.prototype.repeatify = String.prototype.repeatify || function(times) { var str = ''; for (var i = 0; i < times; i++) { str += this; } return str; };</code></pre> <p>这个问题测试了开发人员对于javascript中继承的掌握,以及 prototype 这个属性。这也验证了开发人员是否有能力扩展原生数据类型函数(虽然不应该这么做)。</p> <p>在这里,另一种重点是,展示你意识到如何在不重写可能已经定义的函数。这个需要在自定义函数之前判断函数不存在。</p> <pre> <code class="language-javascript">`String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};``</code></pre> <p>当你被要求一个垫片javascript函数时,这个技巧十分有用。</p> <h2>问题3: 提升变量(Hoisting)</h2> <p>执行以下代码会有什么结果?为什么会这样?</p> <pre> <code class="language-javascript">function test() { console.log(a); console.log(foo()); var a = 1; function foo() { return 2; } } test();</code></pre> <h3>答案</h3> <p>这段代码的执行结果是 undefined 和 2 。</p> <p>这个结果的原因是,变量和函数都被提升了( <a href="/misc/goto?guid=4959728788060362942" rel="nofollow,noindex">hoisted</a> )。因此,那个时候 a 被打印了,它存在函数之中(也就是声明了),但是依然是 undefined 。换言之,上述代码和以下代码是相同的。</p> <pre> <code class="language-javascript">function test() { var a; function foo() { return 2; } console.log(a); console.log(foo()); a = 1; } test();</code></pre> <h2>问题4: this 在javascript中是如何工作的</h2> <p>以下代码的结果是什么?请解释你的答案。</p> <pre> <code class="language-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());</code></pre> <h3>答案</h3> <p>代码打印了 Aurelio De Rosa 和 John Doe 。原因是在javascript中,一个函数的语境,也就是 this 这个关键词引用的,依赖于函数是如何调用的,不是如何定义的。</p> <p>在第一个 console.log() 调用中, getFullname() 是作为 obj.prop 的函数被调用的。因此,这里的语境指向后者并且函数返回对象的 fullname 属性。相反,当 getFullname() 被指定为 test 的变量,那个语境指向全局对象( window )。因为 test 相当于设置为全局对象的属性。因为这个原因,函数返回 window 的一个 fullname 属性,这在这个案例中是在代码片段中第一行设置的。</p> <h2>问题5: call() 和 apply()</h2> <p>修复上一个问题,让最后一个 console.log() 打印出 Aurelio De Rosa 。</p> <h3>答案</h3> <p>这个问题可以通过函数 call() 或者 apply() 强制函数语境。如果你不知道 call() 和 apply() 之间的区别,我推荐阅读文章 <a href="/misc/goto?guid=4958853328148081516" rel="nofollow,noindex">function.call和function.apply之间有和区别?</a> 。在以下代码中,我会用 call() ,但是在这个案例中, apply() 也可以获得相同的结果:</p> <pre> <code class="language-javascript">`console.log(test.call(obj.prop));``</code></pre> <h2>结论</h2> <p>在这篇文章中,我们讨论了,在面试中为了测试javascript开发者,而会问到的五种典型的问题。来自面试的真实问题可能会有所不同,但是涵盖的概念和主题通常都是十分相似的。我希望你愉悦地测试你的能力。万一你不知道所有的答案,不要担心:没有学习和经验不能解决的问题。</p> <p>如果你在面试中被问到了其他有趣的问题,不要犹豫马上来和我们分享吧。这会帮助到很多的开发者。</p> <p> </p> <p>来自:http://www.zcfy.cc/article/5-typical-javascript-interview-exercises-1960.html</p> <p> </p>