26个精选的JavaScript面试问题

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

根据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
难度: ?
在JavaScript中,每一个函数都有各自的作用域(scope)。作用域可以理解为是一个变量的集合以及相应的如何访问它的规则。只有在函数内部的变量才可以访问到该函数域的变量。

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

Q3: 请解释JavaScript中的相等判断
话题: JavaScript
难度: ?
JavaScript中的相等判断有严格判断和带隐式转换的判断两种:

严格判断(strict comparision): 比如===,比较的时候不会隐式转换类型;
抽象判断(abstract comparasion):比如==,比较的时候会隐式转换类型。
var a = "42";
var b = 42;

a == b; // true
a === b; // false
一些简单的规则:

如果两边都是布尔类型的值,使用===;
如果两边是0,"",[],使用===;
所有其它类型,使用==是安全的。而且在很多情况下会简化代码、增加可读性。
Q4: 请解释什么叫做回调函数并提供一个简单的例子
话题: JavaScript
难度: ??
回调函数是一个函数,它被作为参数传入另一个函数,当某些操作结束后,该函数被调用。下面是一个简单的例子,当数组被修改后,调用回调函数打印一行日志。

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
难度: ??
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
难度: ??
JavaScript和TypeScript有两个最基本的类型null和undefined。它们的含义是不同的:

如果还没有被初始化,则是undefined;
如果不可用,则可以用null来表示;
Q7: 请实现如下函数
话题: JavaScript
难度: ??
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
难度: ??
下面是JavaScript内置的可用类型:

string
number
boolean
null和undefined
object
symbol (ES6的新语法)
Q9: 请解释事件冒泡以及如何阻止它?
话题: JavaScript
难度: ??
事件冒泡的概念是指:在最内层的元素上绑定的事件被触发后,会按照嵌套的层次由内向外逐步触发。因此,点击某个孩子节点可能会触发父节点的事件。

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

Q10. 请解释JavaScript中的let关键字
话题: JavaScript
难度: ??
ES6允许你使用let关键字来申明块作用域({...})的变量。

来源: github.com/getify

Q11: 如何检查一个数字是否是整数?
话题: JavaScript
难度: ??
一个最简单的方法是判断除以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
难度: ??
IIFE叫做立即执行表达式,顾名思义,该表达式一被创建就立即执行。

(function IIFE(){
console.log( "Hello!" );
})();
// "Hello!"
该方法常用语避免污染全局的命名空间,因为所以在IIFE中使用的变量外部都无法访问。

来源: stackoverflow.com

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

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

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
难度: ???
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: 请解释undefined和not defined的区别
话题: JavaScript
难度: ???
在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
难度: ???
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
难度: ????
闭包是一个定义在其它函数(父函数)里面的函数,它拥有对父函数里面变量的访问权。闭包拥有如下三个作用域的访问权:

自身的作用域
父作用域
全局作用域
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
难度: ????
你可以通过在函数中声明变量来创建私有变量。因为在函数中,外部无法直接访问。

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

来源: dofactory.com

Q20: 判断给定的字符串是否同态(isomorphic)
话题: JavaScript
难度: ????
首先介绍什么叫做同态:两个字符串,如果A字符串中的每一个字符都可以在B字符串中找到唯一对应,并且顺序一一对应;如果存在这样的函数,那么A和B同态。

paper和title同态
egg和sad不同态
dgg和add同态
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;
}
来源: https://github.com/kennymkchan

译者注:上面的解法并不正确,针对上面的代码,我们略做改动,给出如下正确答案:

/**

  • @param {string} firstString
  • @param {string} secondString
  • @return {boolean}
    */
    var isIsomorphic = function(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) {
    // If letterB has already been added to letterMap, then not isomorphic
    if(secondString.indexOf(letterB) < i){
    return false;
    } else {
    letterMap[letterA] = letterB;
    }
    } else if (letterMap[letterA] !== letterB) {
    // Else 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;
    };
    Leetcode上有相应的题目:Isomorphic Strings - LeetCode

Q21: Transpiling代表了什么意思?
话题: JavaScript
难度: ????
Transpiling是transforming + compiling的合成词。对于一些新的语法,浏览器还不支持。最好的办法就是将其变换到旧的等价的代码,这个过程通常叫做transpiling。

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

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

Babel: 将ES6编译到ES5
Traceur:将ES6,ES7等编译到ES5
来源: You Don’t Know JS, Up &going

Q22: this关键字如何工作?请提供一些例子
话题: JavaScript
难度: ????
在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
难度: ????
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
难度: ????
提升(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
难度: ????
0.1 + 0.2 === 0.3
不要惊讶,其结果是false。因为浮点数在系统内的精确度问题,0.1+0.2的结果并不是0.3,而是0.30000000000000004。
要避免这个问题的方法是指定返回结果的小数位数。

来源: coderbyte.com

Q26: 请描述一下揭示模式(Revealing Module Pattern)
话题: JavaScript
难度: ?????
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

原文地址:https://blog.51cto.com/14516164/2432422

时间: 2024-10-09 18:28:17

26个精选的JavaScript面试问题的相关文章

前端JavaScript面试技巧

第1章 课程简介从几个常见面试开始,讨论针对一个题目的分析思路,总结题目对应的知识点.最后列出所有 JS 知识点的集合 -- JS 知识体系框架.1-1 课程简介(导学)1-2 前言1-3 几个面试题1-4 如何搞定所有面试题 第2章 JS基础知识(上)讲解 JS 基础语法相关的面试题,分析原理以及解答方法.这一章节讲解了基础知识的第一部分:变量的类型和计算.以及JS "三座大山" -- 原型.作用域和异步中的第一座大山:原型.2-1 变量类型和计算-12-2 变量类型和计算-22-3

5个经典的JavaScript面试基础问题

JavaScript程序员在IT领域中的需求量非常巨大.如果你非常精通JavaScript,你会有很多换工作.涨薪水的机会.但是在一家公司录用你之前,你必须顺利通过面试,证明你的技能.在本文中,我将向您展示5个关于JavaScript相关的问题,可以全面地测试面试者JavaScript技能和解决问题的能力.一起来看看这5个经典的JavaScript面试问题. 问题1:Scope作用范围 考虑下面的JavaScript代码: (function() { var a = b = 5; })(); c

JavaScript面试的完美指南(开发者视角)

为了说明 JS 面试的复杂性,首先,请尝试给出以下结果: onsole.log(2.0 == "2" == new Boolean(true) == "1") 十有八九的会给出false, 其实运行结果是true,原因请看 这里. 1) 理解 JS 函数 函数是 JavaScript 的精华,是 JS 一等公民.JS 函数不仅仅是一个普通的函数,与其他语言不同,JS 函数可以赋值给变量,作为参数传递给另一个函数,也可以从另一个函数返回. console.log(sq

抓紧面试前的宝贵时间 快速搞定前端初级JavaScript面试

第1章 课程介绍[说说面试的那些事儿]本章会出几个面试题,分析每道题目设计的知识点,然后总结出一个完整的知识体系.让我们开始 “题目->知识点->解题” 的快乐之旅吧. 第2章 JS基础-变量类型和计算[不会变量,别说你会JS]本章介绍变量的类型和计算的知识点和题目,包括值类型和引用类型区别,类型判断,深拷贝等.变量和类型是一个任何一门语言的基础,不了解的话,会被认为是 JS 语法不过关. 第3章 JS基础-原型和原型链[三座大山之一,必考!!!]本章介绍原型.原型链和 class 相关的知识

快速搞定前端初级JavaScript面试完整版

资源获取链接:点击获取完整教程 抓紧面试前的宝贵时间 快速搞定前端初级JavaScript面试 BAT资深面试官针对时下面试高频考点,帮你解决面试问题.课程不局限于简单地讲解每一个知识点,而是以面试官的角度出发,带你了解前端面试中每个“门道”与“套路”.手把手带你分析考点及解答策略,梳理JS考试体系,帮助前端新人快速通过JS面试部分. 课程紧凑,分秒必争 拒绝题海战术,绝不浪费时间解析典型面试题,分析前端面试核心考点拆解一道题,解决一类题 匠心设计,直击考点 凝聚讲师三年面试课程授课经验结合大量

JavaScript面试问题:事件委托和this

JavaScript不仅门槛低,而且是一门有趣.功能强大和非常重要的语言.各行各业的人发现自己最混乱的选择是JavaSscript编程语言.由 于有着各种各样的背景,所以不是每个人都对JavaScript及其基本原理有广泛的认识.通常来书,除非你去参加工作面试才会去思考为什么或者怎么做, 否则JavaScript只是你工作的内容. 这个系类的目标是深入探讨JavaScript的一些概念和理论.主题来自于 Darcy Clarke的JavaScript典型面试问题列表.希望你不仅仅是为了答案而阅读

1.JavaScript面试

1.1. 简要描述 JavaScript 的数据类型?   参考答案:   JavaScript 的数据类型可以分为原始类型和对象类型. 原始类型包括 string.number 和 boolean 三种.其中,字符串是使用一对单引号 或者一对双引号括起来的任意文本:而数值类型都采用 64 位浮点格式存储,不区分整数和 小数:布尔(逻辑)只能有两个值:true 或 false. 复杂类型指其他对象,如 Array.Date.Object 等. 除此之外,JavaScript 中还有两个特殊的原始

javascript面试指南一(js数据类型,==和===的区别 )

我搜集很多关于js基础的面试题,和大家分享一下祝大家面试成功 Q1,javascript 数据类型有哪些? 不要小看这么问题哦,这个问题很不起眼但是又很难回答 我推荐的答案来自于<javacript语言精髓> JavaScript的简单类型包括数字.字符串.布尔值(true和false).null值和undefined值.其他所有的值都是对象.数字.字符串和布尔值“貌似”对象,因为它们拥有方法,但它们是不可变的.JavaScript中的对象是可变的键-值集合(keyed collections

25 个最基本的 JavaScript 面试问题及答案

1.使用 typeof bar === "object" 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个陷阱? 尽管 typeof bar === "object" 是检查 bar 是否对象的可靠方法,令人惊讶的是在JavaScript中 null 也被认为是对象! 因此,令大多数开发人员惊讶的是,下面的代码将输出 true (而不是false) 到控制台: var bar = null; console.log(typeof bar === "