整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

史上最全的Javascript面试题总结(内附答案)

年来,从事JavaScript的程序员越来越多,JavaScript的曝光率也越来越高,如果你想转行试试JavaScript,不妨收下这份面试题及答案,没准用得上。当然,如果针对这些问题,你有更棒的答案,欢迎移步至评论区。

1、什么是JavaScript?(这是基本题,对很多程序员来说也是送分题!)

JavaScript是客户端和服务器端脚本语言,可以插入到HTML页面中,并且是目前较热门的Web开发语言。同时,JavaScript也是面向对象编程语言。

类似的基本题目还包括:JavaScript都有哪些类型?JavaScript是谁发明的?......

2、列举Java和JavaScript之间的区别?

Java是一门十分完整、成熟的编程语言。相比之下,JavaScript是一个可以被引入HTML页面的编程语言。这两种语言并不完全相互依赖,而是针对不同的意图而设计的。 Java是一种面向对象编程(OOPS)或结构化编程语言,类似的如C ++或C,而JavaScript是客户端脚本语言,它被称为非结构化编程。

3. JavaScript和ASP脚本相比,哪个更快?

JavaScript更快。JavaScript是一种客户端语言,因此它不需要Web服务器的协助来执行。另一方面,ASP是服务器端语言,因此总是比JavaScript慢。值得注意的是,Javascript现在也可用于服务器端语言(nodejs)。

4、什么是负无穷大?

负无穷大是JavaScript中的一个数字,可以通过将负数除以零来得到。

5、如何将JavaScript代码分解成几行吗?

在字符串语句中可以通过在第一行末尾使用反斜杠“\”来完成

例:document.write("This is \a program");

如果不是在字符串语句中更改为新行,那么javaScript会忽略行中的断点。

例:

var x=1, y=2,

z=

x+y;

上面的代码是完美的,但并不建议这样做,因为阻碍了调试。

6、什么是未声明和未定义的变量?

未声明的变量是程序中不存在且未声明的变量。如果程序尝试读取未声明变量的值,则会遇到运行时错误。未定义的变量是在程序中声明但尚未给出任何值的变量。如果程序尝试读取未定义变量的值,则返回未定义的值。

7、如何编写可动态添加新元素的代码?

8、什么是全局变量?这些变量如何声明,使用全局变量有哪些问题?

全局变量是整个代码长度可用的变量,也就是说这些变量没有任何作用域。var关键字用于声明局部变量或对象。如果省略var关键字,则声明一个全局变量。

例:// Declare a global globalVariable = “Test”;

使用全局变量所面临的问题是本地和全局变量名称的冲突。此外,很难调试和测试依赖于全局变量的代码。

9、解释JavaScript中定时器的工作?如果有,也可以说明使用定时器的缺点?

定时器用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码。这通过使用函数setTimeout,setInterval和clearInterval来完成。

  • setTimeout(function,delay)函数用于启动在所述延迟之后调用特定功能的定时器。

  • setInterval(function,delay)函数用于在提到的延迟中重复执行给定的功能,只有在取消时才停止。

  • clearInterval(id)函数指示定时器停止。

定时器在一个线程内运行,因此事件可能需要排队等待执行。

10、ViewState和SessionState有什么区别?

“ViewState”特定于会话中的页面。

“SessionState”特定于可在Web应用程序中的所有页面上访问的用户特定数据。

11、什么是===运算符?

===被称为严格等式运算符,当两个操作数具有相同的值而没有任何类型转换时,该运算符返回true。

12、说明如何使用JavaScript提交表单?

要使用JavaScript提交表单,请使用

document.form [0] .submit();

document.form [0] .submit()

13、元素的样式/类如何改变?

可以通过以下方式完成:

document.getElementById(“myText”).style.fontSize = “20?;

document.getElementById(“myText”).className = “anyclass”;

14、JavaScript中的循环结构都有什么?

For、While、do-while loops

15、如何在JavaScript中将base字符串转换为integer?

parseInt() 函数解析一个字符串参数,并返回一个指定基数的整数。parseInt()将要转换的字符串作为其第一个参数,第二个参数是给定字符串的基础。

为了将4F(基数16)转换为整数,所使用的代码是 :parseInt ("4F", 16);

16、说明“==”和“===”之间的区别?

“==”仅检查值相等,而“===”是一个更严格的等式判定,如果两个变量的值或类型不同,则返回false。

17、3 + 2 +“7”的结果是什么?

由于3和2是整数,它们将直接相加。由于7是一个字符串,它将会被直接连接,所以结果将是57。

18、说明如何检测客户端机器上的操作系统?

为了检测客户端机器上的操作系统,应使用navigator.appVersion字符串(属性)。

19、Javascript中的NULL是什么意思?

NULL用于表示无值或无对象。它意味着没有对象或空字符串,没有有效的布尔值,没有数值和数组对象。

20、delete操作符的功能是什么?

delete操作符用于删除程序中的所有变量或对象,但不能删除使用VAR关键字声明的变量。

21、JavaScript中有哪些类型的弹出框?

Alert、Confirm and、Prompt

22、Void(0)怎么用?

  • Void(0)用于防止页面刷新,并在调用时传递参数“zero”。

  • Void(0)用于调用另一种方法而不刷新页面。

23、如何强制页面加载JavaScript中的其他页面?

必须插入以下代码才能达到预期效果:

24、escape字符是用来做什么的?

使用特殊字符(如单引号,双引号,撇号和&符号)时,将使用转义字符(反斜杠)。在字符前放置反斜杠,使其显示。

例:

25、什么是JavaScript Cookie?

Cookie是用来存储计算机中的小型测试文件,当用户访问网站以存储他们需要的信息时,它将被创建。

26、解释JavaScript中的pop()方法?

pop()方法与shift()方法类似,但不同之处在于Shift方法在数组的开头工作。此外,pop()方法将最后一个元素从给定的数组中取出并返回。然后改变被调用的数组。

例:

var cloths = [“Shirt”, “Pant”, “TShirt”];

cloths.pop();

//Now cloth becomes Shirt,Pant

27、在JavaScript中使用innerHTML的缺点是什么?

如果在JavaScript中使用innerHTML,缺点是:内容随处可见;不能像“追加到innerHTML”一样使用;即使你使用+ = like“innerHTML = innerHTML +'html'”旧的内容仍然会被html替换;整个innerHTML内容被重新解析并构建成元素,因此它的速度要慢得多;innerHTML不提供验证,因此我们可能会在文档中插入有效的和破坏性的HTML并将其中断。

28、break和continue语句的作用?

  • Break语句从当前循环中退出。

  • continue语句继续下一个循环语句。

29、在JavaScript中,dataypes的两个基本组是什么?

  • Primitive

  • Reference types

原始类型是数字和布尔数据类型。引用类型是更复杂的类型,如字符串和日期。

30、如何创建通用对象?

通用对象可以创建为:

var I = new object();

31、operator类型用来做什么?

'Typeof'是一个运算符,用于返回变量类型的字符串描述。

32、哪些关键字用于处理异常?

try... Catch-finally用于处理JavaScript中的异常。

33、JavaScript中不同类型的错误有几种?

有三种类型的错误:

  • Load time errors:该错误发生于加载网页时,例如出现语法错误等状况,称为加载时间错误,并且会动态生成错误。

  • Run time errors:由于在HTML语言中滥用命令而导致的错误。

  • Logical Errors:这是由于在具有不同操作的函数上执行了错误逻辑而发生的错误。

34、在JavaScript中使用的Push方法是什么?

push方法用于将一个或多个元素添加或附加到数组的末尾。使用这种方法,可以通过传递多个参数来附加多个元素。

35、什么是JavaScript中的unshift方法?

Unshift方法就像在数组开头工作的push方法。该方法用于将一个或多个元素添加到数组的开头。

36、对象属性如何分配?

属性按以下方式分配给对象:

obj["class"] = 12;

obj.class = 12;

37、获得CheckBox状态的方式是什么?

alert(document.getElementById('checkbox1')。checked);

如果CheckBox被检查,此警报将返回TRUE。

38、解释window.onload和onDocumentReady?

在载入页面的所有信息之前,不运行onload函数。这导致在执行任何代码之前会出现延迟。

onDocumentReady在加载DOM之后加载代码。这允许早期的代码操纵。

39、你将如何解释JavaScript中的闭包? 什么时候使用?

Closure是与函数返回时保留在内存中的函数相关的本地声明变量。

例如:

40、一个值如何附加到数组?

可以以给定的方式将值附加到数组:

arr [arr.length] = value;

41、解释for-in循环?

for-in循环用于循环对象的属性。

for-in循环的语法是:

在每次循环中,来自对象的一个属性与变量名相关联,循环继续,直到对象的所有属性都被耗尽。

42、描述JavaScript中的匿名函数?

被声明为没有任何命名标识符的函数被称为匿名函数。一般来说,匿名函数在声明后无法访问。

匿名函数声明:

43、.call()和.apply()之间有什么区别?

函数.call()和.apply()在使用上非常相似,只是有一点区别。当程序员知道函数参数的编号时,使用.call(),因为它们必须在调用语句中被提及为参数。另一方面,当不知道数字时使用.apply(),函数.apply()期望参数为数组。

.call()和.apply()之间的基本区别在于将参数传递给函数。它们的用法可以通过给定的例子进行说明。

44、定义事件冒泡?

JavaScript允许DOM元素嵌套在一起。在这种情况下,如果单击子级的处理程序,父级的处理程序也将执行同样的工作。

45、什么样的布尔运算符可以在JavaScript中使用?

“And”运算符(&&),'Or'运算符(||)和'Not'运算符(!)可以在JavaScript中使用。

*运算符没有括号。

46、一个特定的框架如何使用JavaScript中的超链接定位?

可以通过使用“target”属性在超链接中包含所需帧的名称来实现。

<a href=”newpage.htm” target=”newframe”>>New Page</a>

47、在web-garden和web-farm之间有何不同?

web-garden和web-farm都是网络托管系统。唯一的区别是web-garden是在单个服务器中包含许多处理器的设置,而web-farm是使用多个服务器的较大设置。

48、如何分配对象属性?

将属性分配给对象的方式与赋值给变量值相同。例如,表单对象的操作值以下列方式分配为“‘submit”:Document.form.action =“submit”

49、在JavaScript中读取和写入文件的方法是什么?

可以通过使用JavaScript扩展(从JavaScript编辑器运行),打开文件的示例来完成:

fh = fopen(getScriptPath(), 0);

50、在JavaScript中如何使用DOM?

DOM代表文档对象模型,并且负责文档中各种对象的相互交互。DOM是开发网页所必需的,其中包括诸如段落,链接等对象。可以操作这些对象以包括添加或删除等操作,DOM还需要向网页添加额外的功能。除此之外,API的使用比其他更有优势。

51、JavaScript中如何使用事件处理程序?

事件是由用户生成活动(例如单击链接或填写表单)导致的操作。需要一个事件处理程序来管理所有这些事件的正确执行。事件处理程序是对象的额外属性。此属性包括事件的名称以及事件发生时采取的操作。

52、解释延迟脚本在JavaScript中的作用?

默认情况下,在页面加载期间,HTML代码的解析将暂停,直到脚本停止执行。这意味着,如果服务器速度较慢或者脚本特别沉重,则会导致网页延迟。在使用Deferred时,脚本会延迟执行直到HTML解析器运行。这减少了网页加载时间,并且它们的显示速度更快。

53、JavaScript中的各种功能组件是什么?

JavaScript中的不同功能组件是:

  • First-class函数:JavaScript中的函数被用作第一类对象。这通常意味着这些函数可以作为参数传递给其他函数,作为其他函数的值返回,分配给变量,也可以存储在数据结构中。

  • 嵌套函数:在其他函数中定义的函数称为嵌套函数。

54、解释unshift()方法?

该方法在数组启动时起作用,与push()不同。 它将所需数量的元素添加到数组的顶部。例如:

输出如下所示:

[" joseph "," Jane ", " charlie ", " john "]

55、decodeURI()和encodeURI()是什么?

EncodeURl()用于将URL转换为十六进制编码。而DecodeURI()用于将编码的URL转换回正常。

56、为什么不建议在JavaScript中使用innerHTML?

innerHTML内容每次刷新,因此很慢。 在innerHTML中没有验证的余地,因此,更容易在文档中插入错误代码,从而使网页不稳定。

57、如何在不支持JavaScript的旧浏览器中隐藏JavaScript代码?

  • 在<script>标签之后的代码中添加“<! - ”,不带引号。

  • 在<script>标签之前添加“// - >”代码中没有引号。

  • 旧浏览器现在将JavaScript代码视为一个长的HTML注释。而支持JavaScript的浏览器则将“<! - ”和“// - >”作为一行注释。

者|FullStack.Cafe

出处|前端之巅

根据 Stack Overflow 的 2018 年度调查,JavaScript 连续六年成为最常用的编程语言。所以我们必须面对这样的现实,JavaScript 已经成为全栈开发技能的基石,在全栈开发面试中都会不可避免地涉及到与 JavaScript 有关的问题。FullStack.Cafe 汇编了最常见的 JavaScript 面试问题和答案,希望能够帮助读者找到下一份梦想中的工作。

Q1:JavaScript 中的强制转型(coercion)是指什么?

难度:0

在 JavaScript 中,两种不同的内置类型间的转换被称为强制转型。强制转型在 JavaScript 中有两种形式:显式和隐式。

这是一个显式强制转型的例子:

var a = "42";
var b = Number( a );
a; // "42"
b; // 42 -- 是个数字!

这是一个隐式强制转型的例子:

var a = "42";
var b = a * 1; // "42" 隐式转型成 42 
a; // "42"
b; // 42 -- 是个数字!

Q2:JavaScript 中的作用域(scope)是指什么?

难度:⭐

在 JavaScript 中,每个函数都有自己的作用域。作用域基本上是变量以及如何通过名称访问这些变量的规则的集合。只有函数中的代码才能访问函数作用域内的变量。

同一个作用域中的变量名必须是唯一的。一个作用域可以嵌套在另一个作用域内。如果一个作用域嵌套在另一个作用域内,最内部作用域内的代码可以访问另一个作用域的变量。

Q3:解释 JavaScript 中的相等性。

难度:⭐

JavaScript 中有严格比较和类型转换比较:

  • 严格比较(例如 ===)在不允许强制转型的情况下检查两个值是否相等;
  • 抽象比较(例如 ==)在允许强制转型的情况下检查两个值是否相等。


var a = "42";
var b = 42;
a == b; // true
a === b; // false

一些简单的规则:

  • 如果被比较的任何一个值可能是 true 或 false,要用 ===,而不是 ==;
  • 如果被比较的任何一个值是这些特定值(0、“”或 []),要用 ===,而不是 ==;
  • 在其他情况下,可以安全地使用 ==。它不仅安全,而且在很多情况下,它可以简化代码,并且提升代码可读性。

Q4:解释什么是回调函数,并提供一个简单的例子。

难度:⭐⭐

回调函数是可以作为参数传递给另一个函数的函数,并在某些操作完成后执行。下面是一个简单的回调函数示例,这个函数在某些操作完成后打印消息到控制台。

function modifyArray(arr, callback) {
 // 对 arr 做一些操作
 arr.push(100);
 // 执行传进来的 callback 函数
 callback();
}
var arr = [1, 2, 3, 4, 5];
modifyArray(arr, function() {
 console.log("array has been modified", arr);
});

Q5:“use strict”的作用是什么?

难度:⭐⭐

use strict 出现在 JavaScript 代码的顶部或函数的顶部,可以帮助你写出更安全的 JavaScript 代码。如果你错误地创建了全局变量,它会通过抛出错误的方式来警告你。例如,以下程序将抛出错误:

function doSomething(val) {
 "use strict"; 
 x = val + 10;
}

它会抛出一个错误,因为 x 没有被定义,并使用了全局作用域中的某个值对其进行赋值,而 use strict 不允许这样做。下面的小改动修复了这个错误:

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

Q6:解释 JavaScript 中的 null 和 undefined。

难度:⭐⭐

JavaScript 中有两种底层类型:null 和 undefined。它们代表了不同的含义:

  • 尚未初始化的东西:undefined;
  • 目前不可用的东西:null。

Q7:编写一个可以执行如下操作的函数。

难度:⭐⭐


var addSix = createBase(6);
addSix(10); // 返回 16
addSix(21); // 返回 27

可以创建一个闭包来存放传递给函数 createBase 的值。被返回的内部函数是在外部函数中创建的,内部函数就成了一个闭包,它可以访问外部函数中的变量,在本例中是变量 baseNumber。

function createBase(baseNumber) {
 return function(N) {
 // 我们在这里访问 baseNumber,即使它是在这个函数之外声明的。
 // 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:解释事件冒泡以及如何阻止它?

难度:⭐⭐

事件冒泡是指嵌套最深的元素触发一个事件,然后这个事件顺着嵌套顺序在父元素上触发。

防止事件冒泡的一种方法是使用 event.cancelBubble 或 event.stopPropagation()(低于 IE 9)。

Q10:JavaScript 中的 let 关键字有什么用?

难度:⭐⭐

除了可以在函数级别声明变量之外,ES6 还允许你使用 let 关键字在代码块({..})中声明变量。

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

难度:⭐⭐

检查一个数字是小数还是整数,可以使用一种非常简单的方法,就是将它对 1 进行取模,看看是否有余数。

function isInt(num) {
 return num % 1 === 0;
}
console.log(isInt(4)); // true
console.log(isInt(12.2)); // false
console.log(isInt(0.3)); // false

Q12:什么是 IIFE(立即调用函数表达式)?

难度:⭐⭐⭐

它是立即调用函数表达式(Immediately-Invoked Function Expression),简称 IIFE。函数被创建后立即被执行:

(function IIFE(){
 console.log( "Hello!" );
})();
// "Hello!"

在避免污染全局命名空间时经常使用这种模式,因为 IIFE(与任何其他正常函数一样)内部的所有变量在其作用域之外都是不可见的。

Q13:如何在 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 之间的区别吗?

难度:⭐⭐⭐
  • ECMAScript 5(ES5):ECMAScript 的第 5 版,于 2009 年标准化。这个标准已在所有现代浏览器中完全实现。
  • ECMAScript 6(ES6)或 ECMAScript 2015(ES2015):第 6 版 ECMAScript,于 2015 年标准化。这个标准已在大多数现代浏览器中部分实现。

以下是 ES5 和 ES6 之间的一些主要区别:

  • 箭头函数和字符串插值:


const greetings = (name) => {
 return `hello ${name}`;
}
const greetings = name => `hello ${name}`;
  • 常量

常量在很多方面与其他语言中的常量一样,但有一些需要注意的地方。常量表示对值的“固定引用”。因此,在使用常量时,你实际上可以改变变量所引用的对象的属性,但无法改变引用本身。

const NAMES = [];
NAMES.push("Jim");
console.log(NAMES.length === 1); // true
NAMES = ["Steve", "John"]; // error
  • 块作用域变量。

新的 ES6 关键字 let 允许开发人员声明块级别作用域的变量。let 不像 var 那样可以进行提升。

  • 默认参数值

默认参数允许我们使用默认值初始化函数。如果省略或未定义参数,则使用默认值,也就是说 null 是有效值。

// 基本语法
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

promise 提供了一种机制来处理异步操作结果。你可以使用回调来达到同样的目的,但是 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')
})
  • 模块导出和导入


const myModule = { x: 1, y: () => { console.log('This is ES5') }}
export default myModule;
import myModule from './myModule';

问题 15:解释 JavaScript 中“undefined”和“not defined”之间的区别。

难度:⭐⭐⭐

在 JavaScript 中,如果你试图使用一个不存在且尚未声明的变量,JavaScript 将抛出错误“var name is not defined”,让后脚本将停止运行。但如果你使用 typeof undeclared_variable,它将返回 undefined。

在进一步讨论之前,先让我们理解声明和定义之间的区别。

“var x”表示一个声明,因为你没有定义它的值是什么,你只是声明它的存在。

var x; // 声明 x
console.log(x); // 输出: undefined

“var x = 1”既是声明又是定义(我们也可以说它是初始化),x 变量的声明和赋值相继发生。在 JavaScript 中,每个变量声明和函数声明都被带到了当前作用域的顶部,然后进行赋值,这个过程被称为提升(hoisting)。

当我们试图访问一个被声明但未被定义的变量时,会出现 undefined 错误。

var x; // 声明
if(typeof x === 'undefined') // 将返回 true

当我们试图引用一个既未声明也未定义的变量时,将会出现 not defined 错误。

console.log(y); // 输出: ReferenceError: y is not defined

Q16:匿名和命名函数有什么区别?

难度:⭐⭐⭐


var foo = function() { // 赋给变量 foo 的匿名函数
 // ..
};
var x = function bar(){ // 赋给变量 x 的命名函数 bar
 // ..
};
foo(); // 实际执行函数
x();

Q17:Javascript 中的“闭包”是什么?举个例子?

难度:⭐⭐⭐⭐

闭包是在另一个函数(称为父函数)中定义的函数,并且可以访问在父函数作用域中声明和定义的变量。

闭包可以访问三个作用域中的变量:

  • 在自己作用域中声明的变量;
  • 在父函数中声明的变量;
  • 在全局作用域中声明的变量。
var globalVar = "abc";
// 自调用函数
(function outerFunction (outerArg) { // outerFunction 作用域开始
 // 在 outerFunction 函数作用域中声明的变量
 var outerFuncVar = 'x'; 
 // 闭包自调用函数
 (function innerFunction (innerArg) { // innerFunction 作用域开始
 // 在 innerFunction 函数作用域中声明的变量
 var innerFuncVar = "y";
 console.log( 
 "outerArg = " + outerArg + "\n" +
 "outerFuncVar = " + outerFuncVar + "\n" +
 "innerArg = " + innerArg + "\n" +
 "innerFuncVar = " + innerFuncVar + "\n" +
 "globalVar = " + globalVar);
 // innerFunction 作用域结束
 })(5); // 将 5 作为参数
// outerFunction 作用域结束
})(7); // 将 7 作为参数

innerFunction 是在 outerFunction 中定义的闭包,可以访问在 outerFunction 作用域内声明和定义的所有变量。除此之外,闭包还可以访问在全局命名空间中声明的变量。

上述代码的输出将是:

outerArg = 7
outerFuncVar = x
innerArg = 5
innerFuncVar = y
globalVar = abc

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

Q19:请解释原型设计模式。

难度:⭐⭐⭐⭐

原型模式可用于创建新对象,但它创建的不是非初始化的对象,而是使用原型对象(或样本对象)的值进行初始化的对象。原型模式也称为属性模式。

原型模式在初始化业务对象时非常有用,业务对象的值与数据库中的默认值相匹配。原型对象中的默认值被复制到新创建的业务对象中。

经典的编程语言很少使用原型模式,但作为原型语言的 JavaScript 在构造新对象及其原型时使用了这个模式。

Q20:判断一个给定的字符串是否是同构的。

难度:⭐⭐⭐⭐

如果两个字符串是同构的,那么字符串 A 中所有出现的字符都可以用另一个字符替换,以便获得字符串 B,而且必须保留字符的顺序。字符串 A 中的每个字符必须与字符串 B 的每个字符一对一对应。

  • paper 和 title 将返回 true。
  • egg 和 sad 将返回 false。
  • dgg 和 add 将返回 true。
isIsomorphic("egg", 'add'); // true
isIsomorphic("paper", 'title'); // true
isIsomorphic("kick", 'side'); // false
function isIsomorphic(firstString, secondString) {
 // 检查长度是否相等,如果不相等, 它们不可能是同构的
 if (firstString.length !== secondString.length) return false
 var letterMap = {};
 for (var i = 0; i < firstString.length; i++) {
 var letterA = firstString[i],
 letterB = secondString[i];
 // 如果 letterA 不存在, 创建一个 map,并将 letterB 赋值给它
 if (letterMap[letterA] === undefined) {
 letterMap[letterA] = letterB;
 } else if (letterMap[letterA] !== letterB) {
 // 如果 letterA 在 map 中已存在, 但不是与 letterB 对应,
 // 那么这意味着 letterA 与多个字符相对应。
 return false;
 }
 }
 // 迭代完毕,如果满足条件,那么返回 true。
 // 它们是同构的。
 return true;
}

Q21:“Transpiling”是什么意思?

难度:⭐⭐⭐⭐

对于语言中新加入的语法,无法进行 polyfill。因此,更好的办法是使用一种工具,可以将较新代码转换为较旧的等效代码。这个过程通常称为转换(transpiling),就是 transforming + compiling 的意思。

通常,你会将转换器(transpiler)加入到构建过程中,类似于 linter 或 minifier。现在有很多很棒的转换器可选择:

  • Babel:将 ES6+ 转换为 ES5
  • Traceur:将 ES6、ES7 转换为 ES5

Q22:“this”关键字的原理是什么?请提供一些代码示例。

难度:⭐⭐⭐⭐

在 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

Q23:如何向 Array 对象添加自定义方法,让下面的代码可以运行?

难度:⭐⭐⭐⭐


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

JavaScript 不是基于类的,但它是基于原型的语言。这意味着每个对象都链接到另一个对象(也就是对象的原型),并继承原型对象的方法。你可以跟踪每个对象的原型链,直到到达没有原型的 null 对象。我们需要通过修改 Array 原型来向全局 Array 对象添加方法。

Array.prototype.average = function() {
 // 计算 sum 的值
 var sum = this.reduce(function(prev, cur) { return prev + cur; });
 // 将 sum 除以元素个数并返回
 return sum / this.length;
}
var arr = [1, 2, 3, 4, 5];
var avg = arr.average();
console.log(avg); // => 3

Q24:什么是 JavaScript 中的提升操作?

难度:⭐⭐⭐⭐

提升(hoisting)是 JavaScript 解释器将所有变量和函数声明移动到当前作用域顶部的操作。有两种类型的提升:

  • 变量提升——非常少见
  • 函数提升——更常见

无论 var(或函数声明)出现在作用域的什么地方,它都属于整个作用域,并且可以在该作用域内的任何地方访问它。

var a = 2;
foo(); // 因为`foo()`声明被"提升",所以可调用
function foo() {
 a = 3;
 console.log( a ); // 3
 var a; // 声明被"提升"到 foo() 的顶部
}
console.log( a ); // 2

Q25:以下代码输出的结果是什么?

难度:⭐⭐⭐⭐


0.1 + 0.2 === 0.3

这段代码的输出是 false,这是由浮点数内部表示导致的。0.1 + 0.2 并不刚好等于 0.3,实际结果是 0.30000000000000004。解决这个问题的一个办法是在对小数进行算术运算时对结果进行舍入。

Q26:请描述一下 Revealing 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(); // 输出: This is a method I want to expose!
Exposer.second(); // 输出: Inside a private method!
Exposer.methodToExpose; // undefined

它的一个明显的缺点是无法引用私有方法。

英文原文

https://www.fullstack.cafe/blog/top-26-javascript-interview-questions-and-answers-in-2019

TML称为超文本标记语言,是一种标识性的语言。在前端开发中离不开HTML,支持不同数据格式的文件镶入。前端工程师在面试过程中涉及到一些基础知识,常见的前端HTML面试题有哪些呢?本文,千锋武汉Web前端培训小编分享12道经典的HTML面试题给大家!

1、<image>标签上title属性与alt属性的区别是什么?

alt属性是为了给那些不能看到你文档中图像的浏览者提供文字说明的。且长度必须少于100个英文字符或者用户必须保证替换文字尽可能的短。

这包括那些使用本来就不支持图像显示或者图像显示被关闭的浏览器的用户,视觉障碍的用户和使用屏幕阅读器的用户等。

title属性为设置该属性的元素提供建议性的信息。使用title属性提供非本质的额外信息。参考《alt和title属性的区别及应用》

2、分别写出以下几个HTML标签:文字加粗、下标、居中、字体

加粗:<b>、<strong>

下标:<sub>

居中:<center>

字体:<font>、<basefont>、参考《HTML标签列表》

3、请写出至少5个html5新增的标签,并说明其语义和应用场景

section:定义文档中的一个章节

nav:定义只包含导航链接的章节

header:定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。

footer:定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。

aside:定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。

参考《HTML5 标签列表》

4、请说说你对标签语义化的理解?

a. 去掉或者丢失样式的时候能够让页面呈现出清晰的结构

b. 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;

c. 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;

d. 便于团队开发和维护,语义化更具可读性,遵循W3C标准的团队都遵循这个标准,可以减少差异化。

5、Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?

声明位于文档中的最前面,处于 标签之前。告知浏览器以何种模式来渲染文档。

严格模式的排版和 JS 运作模式是,以该浏览器支持的最高标准运行。

在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。

DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。

6、你知道多少种Doctype文档类型?

标签可声明三种 DTD 类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。

HTML 4.01 规定了三种文档类型:Strict、Transitional 以及 Frameset。

XHTML 1.0 规定了三种 XML 文档类型:Strict、Transitional 以及 Frameset。

Standards (标准)模式(也就是严格呈现模式)用于呈现遵循最新标准的网页,

Quirks(包容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页。

7、HTML与XHTML——二者有什么区别

a. XHTML 元素必须被正确地嵌套。

b. XHTML 元素必须被关闭。

c. 标签名必须用小写字母。

d. XHTML 文档必须拥有根元素。

参考《XHTML 与 HTML 之间的差异》

8、html5有哪些新特性、移除了那些元素?

a. HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

b. 拖拽释放(Drag and drop) API

c. 语义化更好的内容标签(header,nav,footer,aside,article,section)

d. 音频、视频API(audio,video)

e. 画布(Canvas) API

f. 地理(Geolocation) API

g. 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失

h. sessionStorage 的数据在页面会话结束时会被清除

i. 表单控件,calendar、date、time、email、url、search

j. 新的技术webworker, websocket等

移除的元素:

a. 纯表现的元素:basefont,big,center, s,strike,tt,u;

b. 对可用性产生负面影响的元素:frame,frameset,noframes;

9、iframe的优缺点?

优点:

a. 解决加载缓慢的第三方内容如图标和广告等的加载问题

b. iframe无刷新文件上传

c. iframe跨域通信

缺点:

a. iframe会阻塞主页面的Onload事件

b. 无法被一些搜索引擎索引到

c. 页面会增加服务器的http请求

d. 会产生很多页面,不容易管理。

参考《iframe的一些记录》

10、Quirks模式是什么?它和Standards模式有什么区别?

在写程序时我们也会经常遇到这样的问题,如何保证原来的接口不变,又提供更强大的功能,尤其是新功能不兼容旧功能时。IE6以前的页面大家都不会去写DTD,所以IE6就假定 如果写了DTD,就意味着这个页面将采用对CSS支持更好的布局,而如果没有,则采用兼容之前的布局方式。这就是Quirks模式(怪癖模式,诡异模式,怪异模式)。

区别:总体会有布局、样式解析和脚本执行三个方面的区别。

a. 盒模型:在W3C标准中,如果设置一个元素的宽度和高度,指的是元素内容的宽度和高度,而在Quirks 模式下,IE的宽度和高度还包含了padding和border。

b. 设置行内元素的高宽:在Standards模式下,给等行内元素设置wdith和height都不会生效,而在quirks模式下,则会生效。

c. 设置百分比的高度:在standards模式下,一个元素的高度是由其包含的内容来决定的,如果父元素没有设置百分比的高度,子元素设置一个百分比的高度是无效的用

d. 设置水平居中:使用margin:0 auto在standards模式下可以使元素水平居中,但在quirks模式下却会失效。

11、请阐述table的缺点

a. 太深的嵌套,比如table>tr>td>h3,会导致搜索引擎读取困难,而且,最直接的损失就是大大增加了冗余代码量。

b. 灵活性差,比如要将tr设置border等属性,是不行的,得通过td

c. 代码臃肿,当在table中套用table的时候,阅读代码会显得异常混乱

d. 混乱的colspan与rowspan,用来布局时,频繁使用他们会造成整个文档顺序混乱。

e. 不够语义

参考《为什么说table表格布局不好?》

12、简述一下src与href的区别

src用于替换当前元素;href用于在当前文档和引用资源之间确立联系。

src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置

href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接

以上千锋武汉Web前端培训小编仅介绍了部分HTML面试题及答案。如果想要在众多竞争者中脱颖而出,除了专业技能还需要掌握一些求职面试的技巧,在面试过程中争取更多的主动权。了解更多Web前端工程师求职面试技巧,你可以关注“武汉千锋”微信公众号,定期发布技术热点文章和求职指南。你也可以来千锋武汉Web前端培训班免费试听两周,亲身感受教学效果,满意后进行系统深入的学习进阶!

千锋武汉Web前端培训课程结合时下流行技术,以实战项目驱动教学,除了培养学员的开发技术,覆盖热门大数据可视化内容,深度贯穿前端后端开发,紧贴主流企业一线需求。这里有专业老师带你,最多半年的时间让你完美蜕变。进名企、拿高薪不再是问题,命运掌握在自己的手里,想要什么样的人生就看你自己的选择了!