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 相关文章推荐
Microsoft Ajax Minifier 压缩javascript的方法
Mar 05 Javascript
jQuery动画与特效详解
Feb 01 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
Jul 05 Javascript
基于JavaScript实现动态创建表格和增加表格行数
Dec 20 Javascript
JS设计模式之策略模式概念与用法分析
Feb 05 Javascript
JS实现二维数组元素的排列组合运算简单示例
Jan 28 Javascript
WebGL three.js学习笔记之阴影与实现物体的动画效果
Apr 25 Javascript
一篇文章弄懂javascript中的执行栈与执行上下文
Aug 09 Javascript
jquery实现直播弹幕效果
Nov 28 jQuery
JS面向对象之单选框实现
Jan 17 Javascript
详解Typescript 内置的模块导入兼容方式
May 31 Javascript
vant picker+popup 自定义三级联动案例
Nov 04 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接收POST数据方式
2015/06/05 PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
2015/12/31 PHP
thinkphp验证码的实现(form、ajax实现验证)
2016/07/28 PHP
PHP堆栈调试操作简单示例
2018/06/15 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
通过修改referer下载文件的方法
2008/05/11 Javascript
Firefox中autocomplete=&quot;off&quot; 设置不起作用Bug的解决方法
2011/03/25 Javascript
浏览器窗口加载和大小改变事件示例
2014/02/27 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
js过滤HTML标签完整实例
2015/11/26 Javascript
Jquery EasyUI实现treegrid上显示checkbox并取选定值的方法
2016/04/29 Javascript
JavaScript中的对象继承关系
2016/08/01 Javascript
jQuery中hover方法搭配css的hover选择器,实现选中元素突出显示方法
2017/05/08 jQuery
NodeJs使用Mysql模块实现事务处理实例
2017/05/31 NodeJs
详解Vue 多级组件透传新方法provide/inject
2018/05/09 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
微信小程序实现的一键复制功能示例
2019/04/24 Javascript
深入探索VueJS Scoped CSS 实现原理
2019/09/23 Javascript
vue过滤器实现日期格式化的案例分析
2020/07/02 Javascript
JavaScript实现刮刮乐效果
2020/11/01 Javascript
在vue项目中封装echarts的步骤
2020/12/25 Vue.js
Python模块文件结构代码详解
2018/02/03 Python
纯CSS改变webkit内核浏览器的滚动条样式
2014/04/17 HTML / CSS
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
医院护士求职自荐信格式
2013/09/21 职场文书
记者岗位职责
2014/01/06 职场文书
幼儿园教学管理制度
2014/02/04 职场文书
党的群众路线教育实践活动宣传方案
2014/02/23 职场文书
考博导师推荐信范文
2015/03/27 职场文书
2015年办公室工作总结范文
2015/03/31 职场文书
五年级数学教学反思
2016/02/16 职场文书
祝福语集锦:朋友新店开业祝福语
2019/12/10 职场文书
多表查询、事务、DCL
2021/04/05 MySQL
python实现黄金分割法的示例代码
2021/04/28 Python
HTML+CSS实现导航条下拉菜单的示例代码
2021/08/02 HTML / CSS
欧元符号 €
2022/02/17 杂记