26个精选的JavaScript面试问题

栏目: JavaScript · 发布时间: 6年前

内容简介:译者按:从各个平台精选整理出26道由浅入深的题目助你面试根据Stack Overflow 2018年年度调查报告,JavaScript已经连续6年保持最常用的编程语言的记录。对于一个全栈工程师,JavaScript可以说是一项必备语言,在面试中总会被问到。我整理了一下FullStack.Cafe上所有常见的JavaScript面试问题供大家参考:话题: JavaScript 难度: 0

译者按:从各个平台精选整理出26道由浅入深的题目助你面试

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

根据Stack Overflow 2018年年度调查报告,JavaScript已经连续6年保持最常用的编程语言的记录。对于一个全栈工程师,JavaScript可以说是一项必备语言,在面试中总会被问到。我整理了一下FullStack.Cafe上所有常见的JavaScript面试问题供大家参考:

Q1: JavaScript中类型转换是怎样的?

话题: JavaScript 难度: 0

在JavaScript中,在两个不同类型之间的转换叫做 coercion 。在JavaScript中有两种形式:显示转换和隐式转换。

下面是一个显示转换的例子:

var a = "42";
var b = Number( a );
a;              // "42"
b;              // 42 -- the number!
复制代码

下面是一个隐式转换的例子:

var a = "42";
var b = a * 1;  // "42" implicitly coerced to 42 here
a;              // "42"
b;              // 42 -- the number!
复制代码

来源:FullStack.Cafe

Q2: JavaScript中的作用域是怎样的?

话题: JavaScript 难度: :star:

在JavaScript中,每一个函数都有各自的作用域( scope )。作用域可以理解为是一个变量的集合以及相应的如何访问它的规则。只有在函数内部的变量才可以访问到该函数域的变量。

在同一个作用域内部,变量名必须要唯一。作用域可以嵌套。在最内部的作用域中,可以访问任何外部的作用域中的变量。

Q3: 请解释JavaScript中的相等判断

话题: JavaScript 难度: :star:

JavaScript中的相等判断有严格判断和带隐式转换的判断两种:

===
==
var a = "42";
var b = 42;

a == b;         // true
a === b;        // false
复制代码

一些简单的规则:

  • 如果两边都是布尔类型的值,使用 === ;
  • 如果两边是0, "" , [] ,使用 === ;
  • 所有其它类型,使用 == 是安全的。而且在很多情况下会简化代码、增加可读性。

Q4: 请解释什么叫做回调函数并提供一个简单的例子

话题: JavaScript 难度: :star::star:

回调函数是一个函数,它被作为参数传入另一个函数,当某些操作结束后,该函数被调用。下面是一个简单的例子,当数组被修改后,调用回调函数打印一行日志。

function modifyArray(arr, callback) {
  // do something to arr here
  arr.push(100);
  // then execute the callback function that was passed
  callback();
}

var arr = [1, 2, 3, 4, 5];
modifyArray(arr, function() {
  console.log("array has been modified", arr);
});
复制代码

Q5: "use strict"到底有何用处?

话题: JavaScript 难度: :star::star:

use strict 放在文件的顶部或则函数的第一行来启动更加严格的检查来避免失误引起的错误。比如,下面的代码会抛出错误:

function doSomething(val) {
  "use strict"; 
  x = val + 10;
}
复制代码

因为x没有定义,如果使用了 use strict ,x是不会被当做全局的变量来看待。下面的代码修复了这个BUG:

function doSomething(val) {
  "use strict"; 
  var x = val + 10;
}
复制代码

Q6: 请解释Null和Undefined

话题: JavaScript 难度: :star::star:

JavaScript和TypeScript有两个最基本的类型 nullundefined 。它们的含义是不同的:

undefined
null

Q7: 请实现如下函数

话题: JavaScript 难度: :star::star:

var addSix = createBase(6);
addSix(10); // returns 16
addSix(21); // returns 27
复制代码

addSix 是一个函数,也就是说createBase函数的返回是一个函数。

function createBase(baseNumber) {
  return function(N) {
    // we are referencing baseNumber here even though it was declared
    // outside of this function. Closures allow us to do this in JavaScript
    return baseNumber + N;
  }
}

var addSix = createBase(6);
addSix(10);
addSix(21);
复制代码

Q8: 请解释JavaScript中的值和类型

话题: JavaScript 难度: :star::star:

下面是JavaScript内置的可用类型:

  • string
  • number
  • boolean
  • null和undefined
  • object
  • symbol (ES6的新语法)

Q9: 请解释事件冒泡以及如何阻止它?

话题: JavaScript 难度: :star::star:

事件冒泡的概念是指:在最内层的元素上绑定的事件被触发后,会按照嵌套的层次由内向外逐步触发。因此,点击某个孩子节点可能会触发父节点的事件。

一个阻止事件冒泡的办法就是使用 event.stopPropagation() ,在IE<9的浏览器上使用 event.cancelBubble()

来源: github.com/kennymkchan

Q10. 请解释JavaScript中的let关键字

话题: JavaScript 难度: :star::star:

ES6允许你使用let关键字来申明块作用域( {...} )的变量。

来源: github.com/getify

Q11: 如何检查一个数字是否是整数?

话题: JavaScript 难度: :star::star:

一个最简单的方法是判断除以1的余数是否为0.

function isInt(num) {
  return num % 1 === 0;
}

console.log(isInt(4)); // true
console.log(isInt(12.2)); // false
console.log(isInt(0.3)); // false
复制代码

来源:coderbyte.com

Q12: 什么叫IIFEs(Immediately Invoked Function Expressions)?

话题: JavaScript 难度: :star::star:

IIFE叫做立即执行表达式,顾名思义,该表达式一被创建就立即执行。

(function IIFE(){
    console.log( "Hello!" );
})();
// "Hello!"
复制代码

该方法常用语避免污染全局的命名空间,因为所以在IIFE中使用的变量外部都无法访问。

来源:stackoverflow.com

Q13: 如果比较JavaScript中的两个对象?

话题: JavaScript 难度: :star::star:

两个非基本类型的值,比如对象(包括函数和数组)都是通过引用的形式来访问。如果直接通过 ===== 来判断,那么只会简单的判断其引用地址是否相同,而不是它们实际对应的值。

如果数组和字符串做比较,那么数组会通过逗号拼接转换为字符串。通过等号判断的时候,两个相同的数组不会相等,但是和相同数据的字符串比较反而相等。

var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";

a == c;     // true
b == c;     // true
a == b;     // false
复制代码

如果要深度比较,可以使用第三方库,比如 deep-equal 或则你自己实现一个比较算法。

Q14: 请解释ES5和ES6的不同点

话题: JavaScript 难度: :star::star::star:

  • ECMAScript 5 (ES5): 第5个ECMAScript版本,于2009年标准化。该标准几乎所有的浏览器都完全支持。
  • ECMAScript 6 (ES6)/ECMAScript 2015 (ES2015): 第6个ECMAScript版本,于2015年标准化。目前各大浏览器还只是部分支持。

接下来介绍它们主要的区别:

  • 箭头函数和字符串嵌入:
const greetings = (name) => {
      return `hello ${name}`;
}
复制代码

甚至:

const greetings = name => `hello ${name}`;
复制代码
  • 常量声明(Const): 如同其它编程语言中的常量一样,但又有不同。这里的 const 代表了 constant reference 。也就是说,你可以修改其指向的对象的值。但是你不能修改其reference的值。
const NAMES = [];
NAMES.push("Jim");
console.log(NAMES.length === 1); // true
NAMES = ["Steve", "John"]; // error
复制代码
  • 块作用域变量:ES6中的新关键字 let 允许允许开发者将变量的作用域限定在块级别。不会像 var 一样变量提升。
  • 参数默认值:允许在函数定义的时候指定默认的值。
// Basic syntax
function multiply (a, b = 2) {
     return a * b;
}
multiply(5); // 10
复制代码
  • 类定义和继承

ES6开始支持定义类(使用 class 关键字),构造函数(使用 constructor 关键字),和 extend 关键字来实现继承。

  • for-of操作

for...of 语句用来迭代访问一个对象的所有属性。

  • Spread操作符:用于对象合并
const obj1 = { a: 1, b: 2 }
const obj2 = { a: 2, c: 3, d: 4}
const obj3 = {...obj1, ...obj2}
复制代码
  • Promise: Promises提供了一个处理异步操作的方法。你可以用回调函数来实现,但是Promise更加简洁和可读。
const isGreater = (a, b) => {
  return new Promise ((resolve, reject) => {
    if(a > b) {
      resolve(true)
    } else {
      reject(false)
    }
    })
}
isGreater(1, 2)
  .then(result => {
    console.log('greater')
  })
 .catch(result => {
    console.log('smaller')
 })
复制代码
  • 模块的export和import。
const myModule = { x: 1, y: () => { console.log('This is ES5') }}
export default myModule;
复制代码
import myModule from './myModule';
复制代码

来源:Bulby.io

Q15: 请解释 undefinednot defined 的区别

话题: JavaScript 难度: :star::star::star:

在JavaScript中,如果你尝试使用不存在的还未申明的变量,JavaScript会抛出错误 var name is not defined 。但是如果你用 typeof 来查看其类型,会返回 undefined

我们先来澄清一下声明和定义的区别: var x 是一个声明,因为你并没有定义其具体的值,你只是声明其存在性。

var x; // declaring x
console.log(x); //output: undefined
复制代码

var x = 1 同时兼具声明和定义,我们也可以叫它初始化。在JavaScript中,每一个变量和函数声明都会被提升到顶部。

如果我们访问一个声明了但是未定义的变量,会返回 undefined

var x; // Declaration
if(typeof x === 'undefined') // Will return true
复制代码

访问一个未声明未定义的变量,会返回not defined错误。

console.log(y);  // Output: ReferenceError: y is not defined
复制代码

来源:stackoverflow.com

Q16: 匿名函数和命名函数的区别?

话题: JavaScript 难度: :star::star::star:

var foo = function() { // anonymous function assigned to variable foo
    // ..
};

var x = function bar(){ // named function (bar) assigned to variable x 
    // ..
};

foo(); // actual function execution
x();
复制代码

译者补充:匿名函数如果不赋值给某个变量,则无法被调用了;命名函数再次被赋值不是多此一举么。

Q17: JavaScript中闭包是什么?请提供一个例子

话题: JavaScript 难度: :star::star::star::star:

闭包是一个定义在其它函数(父函数)里面的函数,它拥有对父函数里面变量的访问权。闭包拥有如下三个作用域的访问权:

  • 自身的作用域
  • 父作用域
  • 全局作用域
var globalVar = "abc";

// Parent self invoking function
(function outerFunction (outerArg) { // begin of scope outerFunction
  // Variable declared in outerFunction function scope
  var outerFuncVar = 'x';    
  // Closure self-invoking function
  (function innerFunction (innerArg) { // begin of scope innerFunction
    // variable declared in innerFunction function scope
    var innerFuncVar = "y";
    console.log(         
      "outerArg = " + outerArg + "\n" +
      "outerFuncVar = " + outerFuncVar + "\n" +
      "innerArg = " + innerArg + "\n" +
      "innerFuncVar = " + innerFuncVar + "\n" +
      "globalVar = " + globalVar);
  // end of scope innerFunction
  })(5); // Pass 5 as parameter
// end of scope outerFunction
})(7); // Pass 7 as parameter
复制代码

innerFunction 是一个闭包,定义在 outerFunction 中,它可以访问 outerFunction 作用域的所有变量。当然,它还可以访问全局变量。

输出结果如下:

outerArg = 7
outerFuncVar = x
innerArg = 5
innerFuncVar = y
globalVar = abc
复制代码

来源: github.com/ganqqwerty

Q18: 在JavaScript中如何创建私有变量?

话题: JavaScript 难度: :star::star::star::star:

你可以通过在函数中声明变量来创建私有变量。因为在函数中,外部无法直接访问。

function func() {
  var priv = "secret code";
}

console.log(priv); // throws error
复制代码

为了访问该变量,可以构造一个帮助函数来返回该值。

function func() {
  var priv = "secret code";
  return function() {
    return priv;
  }
}

var getPriv = func();
console.log(getPriv()); // => secret code
复制代码

来源:coderbyte.com

Q19: 请解释原型模式(Prototype Design Pattern)

话题: JavaScript 难度: :star::star::star::star:

原型模式会创建一个新的对象,但不是创建一个未初始化的对象,而是通过拷贝原型链上的值或则被拷贝对象的值来完成初始化。传统的语言很少使用原型模式,但是JavaScript作为一个基于原型的语言,使用原型模式来创建新的对象。

来源:dofactory.com

Q20: 判断给定的字符串是否同态(isomorphic)

话题: JavaScript 难度: :star::star::star::star:

首先介绍什么叫做同态:两个字符串,如果A字符串中的每一个字符都可以在B字符串中找到唯一对应,并且顺序一一对应;如果存在这样的函数,那么A和B同态。

  • papertitle 同态
  • eggsad 不同态
  • dggadd 同态
isIsomorphic("egg", 'add'); // true
isIsomorphic("paper", 'title'); // true
isIsomorphic("kick", 'side'); // false

function isIsomorphic(firstString, secondString) {

  // Check if the same length. If not, they cannot be isomorphic
  if (firstString.length !== secondString.length) return false

  var letterMap = {};

  for (var i = 0; i < firstString.length; i++) {
    var letterA = firstString[i],
        letterB = secondString[i];

    // If the letter does not exist, create a map and map it to the value
    // of the second letter
    if (letterMap[letterA] === undefined) {
      letterMap[letterA] = letterB;
    } else if (letterMap[letterA] !== letterB) {
      // Eles if letterA already exists in the map, but it does not map to
      // letterB, that means that A is mapping to more than one letter.
      return false;
    }
  }
  // If after iterating through and conditions are satisfied, return true.
  // They are isomorphic
  return true;
}
复制代码

来源: github.com/kennymkchan

Q21: Transpiling 代表了什么意思?

话题: JavaScript 难度: :star::star::star::star:

Transpilingtransforming + compiling 的合成词。对于一些新的语法,浏览器还不支持。最好的办法就是将其变换到旧的等价的代码,这个过程通常叫做 transpiling

典型的,你可以在 build 的过程中加入 transpiler ,就如同 code linterminifier 一样。

已经有很多知名的transpilers可供使用:

  • Babel: 将ES6编译到ES5
  • Traceur:将ES6,ES7等编译到ES5

来源: You Don't Know JS, Up &going

Q22: this 关键字如何工作?请提供一些例子

话题: JavaScript 难度: :star::star::star::star:

在JavaScript中,this总是指向函数的“拥有者”(也就是指向该函数的对象),或则拥有该函数的对象。

function foo() {
    console.log( this.bar );
}

var bar = "global";

var obj1 = {
    bar: "obj1",
    foo: foo
};

var obj2 = {
    bar: "obj2"
};

foo();          // "global"
obj1.foo();     // "obj1"
foo.call( obj2 );  // "obj2"
new foo();       // undefined
复制代码

来源:quirksmode.org

Q23: 如何为Array对象添加你自定义的函数,使得如下代码可以正常工作。

话题: JavaScript 难度: :star::star::star::star:

var arr = [1, 2, 3, 4, 5];
var avg = arr.average();
console.log(avg);
复制代码

JavaScript是一个基于原型的语言。也就是说对象之间通过原型链接,并继承其函数。为了给Array对象添加函数,我们可以修改其原型定义 Array prorotype

Array.prototype.average = function() {
  // calculate sum
  var sum = this.reduce(function(prev, cur) { return prev + cur; });
  // return sum divided by number of elements
  return sum / this.length;
}

var arr = [1, 2, 3, 4, 5];
var avg = arr.average();
console.log(avg); // => 3
复制代码

来源:coderbyte.com

Q24: JavaScript中提升(hoisting)是什么意思?

话题: JavaScript 难度: :star::star::star::star:

提升(hoisting)是指JavaScript的解释器将所有的变量和函数声明都提升到该作用域的顶部,有两种提升类型:

  • 变量提升
  • 函数提升

在一个作用域中通过声明的变量和函数在整个作用域中都可以使用。

var a = 2;
foo();                 // works because `foo()`
                         // declaration is "hoisted"

function foo() {
    a = 3;
    console.log( a );   // 3
    var a;             // declaration is "hoisted"
                         // to the top of `foo()`
}

console.log( a );   // 2
复制代码

虽然 foo() 函数在后面定义,但是在前面也可以调用。

Q25: 如下代码会返回什么结果?

话题: JavaScript 难度: :star::star::star::star:

0.1 + 0.2 === 0.3
复制代码

不要惊讶,其结果是false。因为浮点数在系统内的精确度问题,0.1+0.2的结果并不是0.3,而是0.30000000000000004。 要避免这个问题的方法是指定返回结果的小数位数。

来源:coderbyte.com

Q26: 请描述一下揭示模式(Revealing Module Pattern)

话题: JavaScript 难度: :star::star::star::star::star:

Module pattern的一个变种是 Revealing Module Pattern 。该 设计模式 的目的是做到很好的代码隔离,只是将需要对外公开的变量和函数暴露出来。一个直接的实现如下所示:

var Exposer = (function() {
  var privateVariable = 10;

  var privateMethod = function() {
    console.log('Inside a private method!');
    privateVariable++;
  }

  var methodToExpose = function() {
    console.log('This is a method I want to expose!');
  }

  var otherMethodIWantToExpose = function() {
    privateMethod();
  }

  return {
      first: methodToExpose,
      second: otherMethodIWantToExpose
  };
})();

Exposer.first();        // Output: This is a method I want to expose!
Exposer.second();       // Output: Inside a private method!
Exposer.methodToExpose; // undefined
复制代码

来源:scotch.io

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和 Java 实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

26个精选的JavaScript面试问题

版权声明

转载时请注明作者Fundebug以及本文地址:

blog.fundebug.com/2018/10/18/…

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高效程序的奥秘

高效程序的奥秘

沃瑞恩 / 冯速 / 机械工业出版社 / 2004-5 / 28.00元

本书适合程序库、编译器开发者及追求优美程序设计的人员阅读,适合用作计算机专业高年级学生及研究生的参考用书。  本书直观明了地讲述了计算机算术的更深层次的、更隐秘的技术,汇集了各种编辑的小技巧,包括常购的任务的小算法,2的幂边界和边界检测、位和字节的重排列、整数除法和常量除法、针对整数的基涵义,空间填充曲线、素数公式等。一起来看看 《高效程序的奥秘》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换