10道典型的JavaScript面试题


Posted in Javascript onMarch 22, 2017

问题1: 作用域(Scope)

考虑以下代码:

(function() {
 var a = b = 5;
})();
console.log(b);

控制台(console)会打印出什么?

答案:5

如果 严格模式开启,那么代码就会报错 ” Uncaught ReferenceError: b is not defined” 。请记住,如果这是预期的行为,严格模式要求你显式地引用全局作用域。所以,你需要像下面这么写:

(function() {
 'use strict';
 var a = window.b = 5;
})();
console.log(b);

问题2: 创建 “原生(native)” 方法

在 String 对象上定义一个 repeatify 函数。这个函数接受一个整数参数,来明确字符串需要重复几次。这个函数要求字符串重复指定的次数。举个例子:

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

在这里,另一个关键点是,看你怎样避免重写可能已经定义了的方法。这可以通过在定义自己的方法之前,检测方法是否已经存在。

String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};

问题3: 变量提升(Hoisting)

执行以下代码的结果是什么?为什么?

function test() {
 console.log(a);
 console.log(foo());
 var a = 1;
 function foo() {
  return 2;
 }
}
test();

答案:

这段代码的执行结果是undefined 和 2。

这个结果的原因是,变量和函数都被提升(hoisted) 到了函数体的顶部。因此,当打印变量a时,它虽存在于函数体(因为a已经被声明),但仍然是undefined。换言之,上面的代码等同于下面的代码:

function test() {
 var a;
 function foo() {
  return 2;
 }
 console.log(a);
 console.log(foo());
 a = 1;
} 
test();

问题4: 在javascript中,`this`是如何工作的

以下代码的结果是什么?请解释你的答案。

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 。原因是,JavaScript中关键字this所引用的是函数上下文,取决于函数是如何调用的,而不是怎么被定义的。

在第一个console.log(),getFullname()是作为obj.prop对象的函数被调用。因此,当前的上下文指代后者,并且函数返回这个对象的fullname属性。相反,当getFullname()被赋值给test变量时,当前的上下文是全局对象window,这是因为test被隐式地作为全局对象的属性。基于这一点,函数返回window的fullname,在本例中即为第一行代码设置的。

问题5: call() 和 apply()

修复前一个问题,让最后一个console.log() 打印输出Aurelio De Rosa.

答案:

这个问题可以通过运用call()或者apply()方法强制转换上下文环境。

console.log(test.call(obj.prop));

问题6: 闭包(Closures)

考虑下面的代码:

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
 nodes[i].addEventListener('click', function() {
  console.log('You clicked element #' + i);
 });
}

请问,如果用户点击第一个和第四个按钮的时候,控制台分别打印的结果是什么?为什么?

答案:

两次打印都是nodes.length的值。

问题7: 闭包(Closures)

修复上题的问题,使得点击第一个按钮时输出0,点击第二个按钮时输出1,依此类推。

答案:

有多种办法可以解决这个问题,下面主要使用两种方法解决这个问题。

第一个解决方案使用立即执行函数表达式(IIFE)再创建一个闭包,从而得到所期望的i的值。实现此方法的代码如下:

var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
 nodes[i].addEventListener('click', (function(i) {
  return function() {
   console.log('You clicked element #' + i);
  }
 })(i));
}

另一个解决方案不使用IIFE,而是将函数移到循环的外面。这种方法由下面的代码实现:

function handlerWrapper(i) {
 return function() {
  console.log('You clicked element #' + i);
 }
}
var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
 nodes[i].addEventListener('click', handlerWrapper(i));
}

问题8:数据类型

考虑如下代码:

console.log(typeof null);
console.log(typeof {});
console.log(typeof []);
console.log(typeof undefined);

答案:

object
object
object
undefined

问题9:事件循环

下面代码运行结果是什么?请解释。

function printing() {
 console.log(1);
 setTimeout(function() { console.log(2); }, 1000);
 setTimeout(function() { console.log(3); }, 0);
 console.log(4);
}
printing();

答案:

1
4
3
2

想知道为什么输出顺序是这样的,你需要弄了解setTimeout()做了什么,以及浏览器的事件循环原理。浏览器有一个事件循环用于检查事件队列,处理延迟的事件。UI事件(例如,点击,滚动等),Ajax回调,以及提供给setTimeout()和setInterval()的回调都会依次被事件循环处理。因此,当调用setTimeout()函数时,即使延迟的时间被设置为0,提供的回调也会被排队。回调会呆在队列中,直到指定的时间用完后,引擎开始执行动作(如果它在当前不执行其他的动作)。因此,即使setTimeout()回调被延迟0毫秒,它仍然会被排队,并且直到函数中其他非延迟的语句被执行完了之后,才会执行。

问题10:算法

写一个isPrime()函数,当其为质数时返回true,否则返回false。

答案:

我认为这是面试中最常见的问题之一。然而,尽管这个问题经常出现并且也很简单,但是从被面试人提供的答案中能很好地看出被面试人的数学和算法水平。

首先, 因为JavaScript不同于C或者Java,因此你不能信任传递来的数据类型。如果面试官没有明确地告诉你,你应该询问他是否需要做输入检查,还是不进行检查直接写函数。严格上说,应该对函数的输入进行检查。

第二点要记住:负数不是质数。同样的,1和0也不是,因此,首先测试这些数字。此外,2是质数中唯一的偶数。没有必要用一个循环来验证4,6,8。再则,如果一个数字不能被2整除,那么它不能被4,6,8等整除。因此,你的循环必须跳过这些数字。如果你测试输入偶数,你的算法将慢2倍(你测试双倍数字)。可以采取其他一些更明智的优化手段,我这里采用的是适用于大多数情况的。例如,如果一个数字不能被5整除,它也不会被5的倍数整除。所以,没有必要检测10,15,20等等。

最后一点,你不需要检查比输入数字的开方还要大的数字。我感觉人们会遗漏掉这一点,并且也不会因为此而获得消极的反馈。但是,展示出这一方面的知识会给你额外加分。

现在你具备了这个问题的背景知识,下面是总结以上所有考虑的解决方案:

function isPrime(number) {
 // If your browser doesn't support the method Number.isInteger of ECMAScript 6,
 // you can implement your own pretty easily
 if (typeof number !== 'number' || !Number.isInteger(number)) {
  // Alternatively you can throw an error.
  return false;
 }
 if (number < 2) {
  return false;
 }
 if (number === 2) {
  return true;
 } else if (number % 2 === 0) {
  return false;
 }
 var squareRoot = Math.sqrt(number);
 for(var i = 3; i <= squareRoot; i += 2) {
  if (number % i === 0) {
   return false;
  }
 }
 return true;
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
Javascript的各种节点操作实例演示代码
Jun 27 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
Sep 02 Javascript
使用jquery中height()方法获取各种高度大全
Apr 02 Javascript
JavaScript实现拖拽网页内元素的方法
Apr 15 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
Feb 23 Javascript
jQuery命名空间与闭包用法示例
Jan 12 Javascript
js操作浏览器的参数方法
Jan 21 Javascript
js表单序列化判断空值的实例
Sep 22 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
Nov 09 Javascript
Vue三层嵌套路由的示例代码
May 05 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
Sep 09 Javascript
利用layer实现表单完美验证的方法
Sep 26 Javascript
jQuery插件FusionCharts绘制ScrollColumn2D图效果示例【附demo源码下载】
Mar 22 #jQuery
js弹出窗口简单实现代码
Mar 22 #Javascript
js实现自动图片轮播代码
Mar 22 #Javascript
JavaScript中清空数组的三种方式
Mar 22 #Javascript
javascript实现多张图片左右无缝滚动效果
Mar 22 #Javascript
tab栏切换原理
Mar 22 #Javascript
js中的DOM模拟购物车功能
Mar 22 #Javascript
You might like
CodeIgniter启用缓存和清除缓存的方法
2014/06/12 PHP
PHP substr()函数参数解释及用法讲解
2017/11/23 PHP
php文件上传原理与实现方法详解
2019/12/20 PHP
javascript firefox兼容ie的dom方法脚本
2008/05/18 Javascript
JavaScript 关键字屏蔽实现函数
2009/08/02 Javascript
基于Jquery的简单图片切换效果
2011/01/06 Javascript
用原生JavaScript实现jQuery的$.getJSON的解决方法
2013/05/03 Javascript
计算新浪Weibo消息长度(还可以输入119字)
2013/07/02 Javascript
SinaEditor使用方法详解
2013/12/28 Javascript
使用百度地图api实现根据地址查询经纬度
2014/12/11 Javascript
js简单实现竖向tab选项卡的方法
2015/05/04 Javascript
jquery仿百度百科底部浮动导航特效
2015/08/08 Javascript
BootStrap智能表单实战系列(七)验证的支持
2016/06/13 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
2018/01/17 Javascript
微信小程序radio组件使用详解
2018/01/31 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
基于JavaScript 实现拖放功能
2019/09/12 Javascript
Node在Controller层进行数据校验的过程详解
2020/08/28 Javascript
javascript实现电商放大镜效果
2020/11/23 Javascript
[05:17]DOTA2睡衣妹卖萌求签名 CJ第二天全明星影像
2013/07/28 DOTA
Python中你应该知道的一些内置函数
2017/03/31 Python
python实现批量修改图片格式和尺寸
2018/06/07 Python
由面试题加深对Django的认识理解
2019/07/19 Python
python实现邮件自动发送
2019/08/10 Python
python实现处理mysql结果输出方式
2020/04/09 Python
PyCharm最新激活码(2020/10/27全网最新)
2020/10/27 Python
H5仿微信界面教程(一)
2017/07/05 HTML / CSS
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
一些PHP的面试题
2015/05/06 面试题
Linux如何为某个操作添加别名
2013/03/01 面试题
超市业务员岗位职责
2013/12/05 职场文书
学校介绍信范文
2014/01/14 职场文书
就业协议书范本
2014/10/08 职场文书
2014年科研工作总结
2014/12/03 职场文书
趣味运动会口号
2015/12/24 职场文书
带你了解CSS基础知识,样式
2021/07/21 HTML / CSS