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 中文字符串处理额外注意事项
Nov 15 Javascript
eclipse导入jquery包后报错的解决方法
Feb 17 Javascript
JavaScript获取路径设计源码
May 22 Javascript
JavaScript的各种常见函数定义方法
Sep 16 Javascript
jQuery判断当前点击的是第几个li的代码
Sep 26 Javascript
Lab.js初次使用笔记
Feb 28 Javascript
深入解析JavaScript中的立即执行函数
May 21 Javascript
jQuery height()、innerHeight()、outerHeight()函数的区别详解
May 23 Javascript
JavaScript实现的XML与JSON互转功能详解
Feb 16 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
Jan 28 Javascript
vue插槽slot的简单理解与用法实例分析
Mar 14 Javascript
Openlayers显示地理位置坐标的方法
Sep 28 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
通过对服务器端特性的配置加强php的安全
2006/10/09 PHP
PHP5与MySQL数据库操作常用代码 收集
2010/03/21 PHP
Laravel 5框架学习之子视图和表单复用
2015/04/09 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
php探针使用原理和技巧讲解
2019/09/17 PHP
JS中Date日期函数中的参数使用介绍
2014/01/02 Javascript
jquery缓动swing liner控制动画过程不同时刻的速度
2014/05/29 Javascript
JavaScript Math.ceil 方法(对数值向上取整)
2015/01/09 Javascript
JavaScript设置获取和设置属性的方法
2015/03/04 Javascript
JS判断图片是否加载完成方法汇总(最新版)
2016/05/13 Javascript
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
2017/03/06 Javascript
jQuery常用选择器详解
2017/07/17 jQuery
深入理解Vue 单向数据流的原理
2017/11/09 Javascript
详解Angular中通过$location获取地址栏的参数
2018/08/02 Javascript
详解在Python中处理异常的教程
2015/05/24 Python
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
Python实现多线程抓取网页功能实例详解
2017/06/08 Python
Python实现运行其他程序的四种方式实例分析
2017/08/17 Python
python+opencv实现的简单人脸识别代码示例
2017/11/14 Python
Python类的继承和多态代码详解
2017/12/27 Python
Python检查ping终端的方法
2019/01/26 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
python如何实现复制目录到指定目录
2020/02/13 Python
python调用jenkinsAPI构建jenkins,并传递参数的示例
2020/12/09 Python
CSS3属性box-shadow使用指南
2014/12/09 HTML / CSS
美国床垫和床上用品公司:Nest Bedding
2017/06/12 全球购物
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
台湾旅游网站:灿星旅游
2018/10/11 全球购物
什么是数据库锁?Oracle中都有哪些类型的锁?
2015/08/21 面试题
寄语十八大感言
2014/02/07 职场文书
公司年会主持词
2014/03/22 职场文书
《卖木雕的少年》教学反思
2014/04/11 职场文书
亲子活动总结
2014/04/26 职场文书
英文感谢信格式
2015/01/21 职场文书
超搞笑婚前保证书
2015/05/08 职场文书
python如何读取和存储dict()与.json格式文件
2022/06/25 Python