前端面试题库 面试题 JS难题,做对一半就是高手(二)

简介: 前端面试题库 面试题 JS难题,做对一半就是高手(二)

前端面试题库 面试题 JS难题,做对一半就是高手(一):https://developer.aliyun.com/article/1413314


23. 谨记优先级

[1 < 2 < 3, 3 < 2 < 1]
// A. [true, true]
// B. [true, false]
// C. error
// D. other

答案是A。<和>的优先级都是从左到右,所以 1 < 2 < 3 会先比较 1 < 2,这会得到 true,但是 < 要求比较的两边都是数字,所以会发生隐式强制转换,将 true 转换成 1,所以最后就变成了比较 1 < 3,结果显然为 true。同理可以分析后者。参考资料:

  • MDN:运算符优先级

24. 坑爹中的战斗机

// the most classic wtf
2 == [[[2]]]
// A. true
// B. false
// C. undefined
// D. other

答案是A。根据ES5规范,如果比较的两个值中有一个是数字类型,就会尝试将另外一个值强制转换成数字,再进行比较。而数组强制转换成数字的过程会先调用它的 toString方法转成字符串,然后再转成数字。所以 [2]会被转成 2,然后递归调用,最终 [[[2]]] 会被转成数字 2。

25. 小数点魔术

3.toString();
3..toString();
3...toString();
// A. 3, error, error
// B. 3, 3.0, error
// C. error, 3, error
// D. other

答案是C。点运算符会被优先识别为数字常量的一部分,然后才是对象属性访问符。所以 3.toString() 实际上被JS引擎解析成 (3.)toString(),显然会出现语法错误。但是如果你这么写 (3).toString(),人为加上括号,这就是合法的。

26. 自动提升为全局变量

(function() {
  var x = y = 1;
})();
console.log(y);
console.log(x);
// A. 1, 1
// B. error, error
// C. 1, error
// D. other

答案是C。很经典的例子,在函数中没有用 var 声明变量 y,所以 y 会被自动创建在全局变量 window下面,所以在函数外面也可以访问得到。而 x 由于被 var 声明过,所以在函数外部是无法访问的。

27. 正则表达式实例

var a = /123/;
var b = /123/;
a == b;
a === b;
// A. true, true
// B. true, false
// C. false, false
// D. other

答案是C。每个字面的正则表达式都是一个单独的实例,即使它们的内容相同。

28. 数组也爱比大小

var a = [1, 2, 3];
var b = [1, 2, 3];
var c = [1, 2, 4];
a == b;
a === b;
a > c;
a < c;
// A. false, false, false, true
// B. false, false, false, false
// C. true, true, false, true
// D. other

答案是A。数组也是对象,ES5规范指出如果两个对象进行相等比较,只有在它们指向同一个对象的情况下才会返回 true,其他情况都返回 false。而对象进行大小比较,会调用 toString 方法转成字符串进行比较,所以结果就变成了字符串 1,2,3 和 1,2,4 按照字典序进行比较了(你若不信,可以重现两个变量的 toString 方法,进行测试)。

手机上刷题  更方便  

WX搜索 【MST题库】小程序查看

29. 原型把戏

var a = {};
var b = Object.prototype;
[a.prototype === b, Object.getPrototypeOf(a) == b]
// A. [false, true]
// B. [true, true]
// C. [false, false]
// D. other

答案是A。对象是没有 prototype 属性的,所以 a.prototype 是 undefined,但我们可以通过 Object.getPrototypeOf 方法来获取一个对象的原型。

30. 构造函数的函数

function f() {}
var a = f.prototype;
var b = Object.getPrototypeOf(f);
a === b;
// A. true
// B. false
// C. null
// D. other

答案是B。这个解释起来有点绕口,我们先来看另外一段代码:

function Person() {}
var p = new Person();
var a = p.__proto__;
var b = Object.getPrototypeOf(p);
var c = Person.prototype;
console.log(a === b, a === c, b === c);
// true, true, true
var d = Person.__proto__;
var e = Object.getPrototypeOf(Person);
var f = Function.prototype;
console.log(d === e, d === f, e === f);
// true, true, true

首先你要明白,任何函数都是 Function 的实例,而p是函数 Person 的实例,Object.getPrototypeOf 会获取构造当前对象的原型。所以 Object.getPrototypeOf(p) === Person.prototype,而 Object.getPrototypeOf(Person) === Function.prototype,所以答案就很明显了。我解释的不是很好,如果读者有更好的解释,欢迎评论。

31. 禁止修改函数名

function foo() {}
var oldName = foo.name;
foo.name = bar;
[oldName, foo.name];
// A. error
// B. [, ]
// C. [foo, foo]
// D. [foo, bar]

答案是C。函数名是禁止修改的,规范写的很清楚,所以这里的修改无效。参考资料:

  • MDN:Function.name

32. 替换陷阱

1 2 3.replace(/\d/g, parseInt);
// A. 1 2 3
// B. 0 1 2
// C. NaN 2 3
// D. 1 NaN 3

答案是D。如果 replace 方法第二个参数是一个函数,则会在匹配的时候多次调用,第一个参数是匹配的字符串,第二个参数是匹配字符串的下标。所以变成了调用 parseInt(1, 0)、parseInt(2, 2)和parseInt(3, 4),结果你就懂了。参考资料:

  • MDN:String.prototype.replace()

33. Function的名字

function f() {}
var parent = Object.getPrototypeOf(f);
console.log(f.name);
console.log(parent.name);
console.log(typeof eval(f.name));
console.log(typeof eval(parent.name));
// A. f, Empty, function, function
// B. f, undefined, function, error
// C. f, Empty, function, error
// D. other

答案是C。根据第30题的解释,我们知道代码中的 parent 实际上就是 Function.prototype,而它在控制台中输出为:

function () {
  [native code]
}

它的 name 属性是 ,所以你 eval()是得不到任何东西的。

手机上刷题  更方便  

WX搜索 【MST题库】小程序查看

34. 正则测试陷阱

var lowerCaseOnly = /^[a-z]+$/;
[lowerCaseOnly.test(null), lowerCaseOnly.test()]
// A. [true, false]
// B. error
// C. [true, true]
// D. [false, true]

答案是C。test 方法的参数如果不是字符串,会经过抽象 ToString操作强制转成字符串,因此实际上测试的是字符串 null 和 undefined。

35. 逗号定义数组

[,,,].join(, )
// A. , , , 
// B. undefined, undefined, undefined, undefined
// C. , , 
// D. 

答案是C。JavaScript允许用逗号来定义数组,得到的数组是含有3个 undefined 值的数组。MDN关于 join 方法的描述:

所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是undefined 或者null, 则会转化成空字符串。

参考资料:

  • MDN:Array.prototype.join()

36. 保留字 class

var a = {class: Animal, name: Fido};
console.log(a.class);
// A. Animal
// B. Object
// C. an error
// D. other

答案是D。实际上真正的答案取决于浏览器。class 是保留字,但是在Chrome、Firefox和Opera中可以作为属性名称,在IE中是禁止的。另一方面,其实所有浏览器基本接受大部分的关键字(如:int、private、throws等)作为变量名,而class是禁止的。

37. 无效日期

var a = new Date(epoch);
// A. Thu Jan 01 1970 01:00:00 GMT+0100(CET)
// B. current time
// C. error
// D. other

答案是D。实际结果是 Invalid Date,它实际上是一个Date对象,因为 a instance Date 的结果是 true,但是它是无效的Date。Date对象内部是用一个数字来存储时间的,在这个例子中,这个数字是 NaN。

38. 神鬼莫测的函数长度

var a = Function.length;
var b = new Function().length;
console.log(a === b);
// A. true
// B. false
// C. error
// D. other

答案是B。实际上a的值是1,b的值是0。还是继续来看MDN文档关于 Function.length 的描述吧!Function构造器的属性:

Function 构造器本身也是个Function。他的 length 属性值为 1 。该属性 Writable: false, Enumerable: false, Configurable: true。

Function原型对象的属性:

Function原型对象的 length 属性值为 0 。

所以,在本例中,a代表的是 Function 构造器的 length 属性,而b代表的是 Function 原型的 length 属性。参考资料:

  • MDN:Function.length

39. Date的面具

var a = Date(0);
var b = new Date(0);
var c = new Date();
[a === b, b === c, a === c];
// A. [true, true, true]
// B. [false, false, false]
// C. [false, true, false]
// D. [true, false, false]

答案是B。先看MDN关于Date对象的注意点:

需要注意的是只能通过调用 Date 构造函数来实例化日期对象:以常规函数调用它(即不加 new 操作符)将会返回一个字符串,而不是一个日期对象。另外,不像其他JavaScript 类型,Date 对象没有字面量格式。

所以a是字符串,b和c是Date对象,并且b代表的是1970年那个初始化时间,而c代表的是当前时间。参考资料:

  • MDN:Date

手机上刷题  更方便  

WX搜索 【MST题库】小程序查看

40. min与max共舞

var min = Math.min();
var max = Math.max();
console.log(min < max);
// A. true
// B. false
// C. error
// D. other

答案是B。看MDN文档,对 Math.min的描述:

如果没有参数,结果为Infinity。

对 Math.max 的描述:

如果没有参数,结果为-Infinity。

参考资料:

  • MDN:Math.min
  • MDN:Math.max

41. 警惕全局匹配

function captureOne(re, str) {
  var match = re.exec(str);
  return match && match[1];
}
var numRe = /num=(\d+)/ig,
      wordRe = /word=(\w+)/i,
      a1 = captureOne(numRe, num=1),
      a2 = captureOne(wordRe, word=1),
      a3 = captureOne(numRe, NUM=1),
      a4 = captureOne(wordRe, WORD=1);
[a1 === a2, a3 === a4]
// A. [true, true]
// B. [false, false]
// C. [true, false]
// D. [false, true]

答案是C。看MDN关于 exec 方法的描述:

当正则表达式使用 g 标志时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的  lastIndex 属性指定的位置开始。

所以a3的值为 null。参考资料:

  • MDN:RegExp.prototype.exec()

42. 最熟悉的陌生人

var a = new Date(2014-03-19);
var b = new Date(2014, 03, 19);
[a.getDay() == b.getDay(), a.getMonth() == b.getMonth()]
// A. [true, true]
// B. [true, false]
// C. [false, true]
// D. [false, false]

答案是D。先看MDN关于Date的一个注意事项:

当Date作为构造函数调用并传入多个参数时,如果数值大于合理范围时(如月份为13或者分钟数为70),相邻的数值会被调整。比如 new Date(2013, 13, 1)等于new Date(2014, 1, 1),它们都表示日期2014-02-01(注意月份是从0开始的)。其他数值也是类似,new Date(2013, 2, 1, 0, 70)等于new Date(2013, 2, 1, 1, 10),都表示时间2013-03-01T01:10:00。

此外,getDay 返回指定日期对象的星期中的第几天(0~6),所以,你懂的。参考资料:

  • MDN:Date

43. 匹配隐式转换

if(http://giftwrapped.com/picture.jpg.match(.gif)) {
  console.log(a gif file);
} else {
  console.log(not a gif file);
}
// A. a gif file
// B. not a gif file
// C. error
// D. other

答案是A。看MDN对 match 方法的描述:

如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj)

将其转换为正则表达式对象。

所以我们的字符串 .gif 会被转换成正则对象 /.gif/,会匹配到 /gif。参考资料:

  • MDN:String.prototype.match()

手机上刷题  更方便  

WX搜索 【MST题库】小程序查看

44. 重复声明变量

function foo(a) {
  var a;
  return a;
}
function bar(a) {
  var a = bye;
  return a;
}
[foo(hello), bar(hello)]
// A. [hello, hello]
// B. [hello, bye]
// C. [bye, bye]
// D. other

答案是B。一个变量在同一作用域中已经声明过,会自动移除 var 声明,但是赋值操作依旧保留,结合前面提到的变量提升机制,你就明白了。参考资料:

手机上刷题  更方便  

WX搜索 【MST题库】小程序查看

相关文章
|
27天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
48 0
|
24天前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
1月前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
35 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
29天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
34 4
|
1月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
110 1
|
1月前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
40 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
1月前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
47 1
|
1月前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
35 1
|
1月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
66 1