js常见面试题(一)

作者 : 开心源码 本文共5342个字,预计阅读时间需要14分钟 发布时间: 2022-05-13 共191人阅读

1、使用typeof bar ===“object”来确定bar能否是一个对象时有什么潜在的缺陷?这个圈套如何避免?

虽然typeof bar ===“object”是检查bar能否是对象的可靠方法,但JavaScript中令人惊讶的问题是null也被认为是一个对象!

因而,对于大多数开发人员来说,下面的代码会将真实(而不是错误)记录到控制台:

var bar = null;console.log(typeof bar === "object"); // true

只需知道这一点,即可以通过检查bar能否为空来轻松避免该问题:

console.log((bar !== null) && (typeof bar === "object")); // false

为了在我们的答案更加的完整,还有两件事值得注意:

首先,假如bar是一个函数,上面的处理方案将返回false。在大多数情况下,这是所期望的行为,但是在您希望函数返回true的情况下,您可以将上述处理方案修改为:

console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));

其次,假如bar是数组,则上述处理方案将返回true(例如,假如var bar = [];)。在大多数情况下,这是所希望的行为,由于数组的确是对象,但是在您想要对数组也是false的情况下,可以将上述处理方案修改为:

console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]"));

但是,还有一个替代方法对空值,数组和函数返回false,但对于对象则为true:

console.log((bar !== null) && (bar.constructor === Object));

isArray使得数组的情况非常简单,包括它自己的空检查:

console.log(Array.isArray(bar));

2、下面的代码将输出到控制台的是什么,为什么?

(function(){  var a = b = 3;})();console.log("a defined? " + (typeof a !== 'undefined'));console.log("b defined? " + (typeof b !== 'undefined'));

因为a和b都在函数的封闭范围内定义,并且因为它们所在的行以var关键字开头,因而大多数JavaScript开发人员会希望typeof a和typeof b在上面的示例中都未定义。

但是,情况并非如此。这里的问题是大多数开发人员错误地了解语句var a = b = 3;以下简写为

var b = 3;var a = b;

但实际上,var a = b = 3;其实是速记:

b = 3;var a = b;

因而(假如您不使用严格模式),代码片段的输出将为:

a defined? falseb defined? true

但是如何在封闭函数的范围之外定义b?那么,由于公告var a = b = 3;是语句b = 3的简写;并且var a = b; b最终成为一个全局变量(由于它不在var关键字后面),因而它依然在作用域内,即便在封闭函数之外。

注意,在严格模式下(即,使用strict),语句var a = b = 3;会产生一个ReferenceError的运行时错误:b没有定义,从而避免了可能导致的任何头headfakes/bugs。 (这就是为什么你应该在你的代码中使用strict,一个重要的例子!)

3、下面的代码将输出到控制台的是什么?,为什么?

var myObject = {        foo: "bar",    func: function() {        var self = this;               console.log("outer func:  this.foo = " + this.foo);               console.log("outer func:  self.foo = " + self.foo);        (function() {                      console.log("inner func:  this.foo = " + this.foo);                 console.log("inner func:  self.foo = " + self.foo);        }());    }};myObject.func();

以上代码将输出到控制台:

outer func:  this.foo = barouter func:  self.foo = barinner func:  this.foo = undefinedinner func: self.foo = bar

在外部函数中,this和self都引用myObject,因而都可以正确地引用和访问foo。

但在内部函数中,这不再指向myObject。因而,this.foo在内部函数中是未定义的,而对局部变量self的引用依然在范围内并且可以在那里访问。

4、在功能块中封装JavaScript源文件的一律内容的重要性和起因是什么?

这是一种日益普遍的做法,被许多流行的JavaScript库(jQuery,Node.js等)所采用。这种技术在文件的一律内容附近创立一个闭包,这可能最重要的是创立一个私有名称空间,从而有助于避免不同JavaScript模块和库之间的潜在名称冲突。

这种技术的另一个特点是为全局变量提供一个容易引用(可能更短)的别名。

5、在JavaScript源文件的开头包含’use strict’的意义和有什么好处?

这里最简单也是最重要的答案是use strict是一种在运行时自动执行更严格的JavaScript代码解析和错误解决的方法。

假如代码错误被忽略或者失败,将会产生错误或者抛出异常。总的来说,这是一个很好的做法。

严格模式的少量主要优点包括:

  • 使调试更容易 假如代码错误原本会被忽略或者失败,那么现在将会产生错误或者抛出异常,从而更快地发现代码中的问题,并更快地指引它们的源代码。
  • 防止意外全局 假如没有严格模式,将值赋给未公告的变量会自动创立一个具备该名称的全局变量。这是JavaScript中最常见的错误之一。在严格模式下,尝试这样做会引发错误。
  • 消除隐藏威胁 在没有严格模式的情况下,对null或者undefined的这个值的引用会自动强制到全局。这可能会导致许多headfakes和pull-out-your-hair类型的错误。在严格模式下,引用null或者undefined的这个值会引发错误。
  • 不允许重复的参数值 严格模式在检测到函数的重复命名参数(例如,函数foo(val1,val2,val1){})时会引发错误,从而捕获代码中几乎可以一定存在的错误,否则您可能会白费大量的时间追踪。
  • 使eval()更安全 eval()在严格模式和非严格模式下的行为方式有些不同。最重要的是,在严格模式下,在eval()语句内部公告的变量和函数不会在包含范围中创立(它们是以非严格模式在包含范围中创立的,这也可能是问题的常见来源)。
  • 抛出无效的使用错误的删除符 删除操作符(用于从对象中删除属性)不能用于对象的不可配置属性。当试图删除一个不可配置的属性时,非严格代码将自动失败,而在这种情况下,严格模式会引发错误

6、考虑下面的两个函数。他们都会返回同样的值吗?为什么或者者为什么不?

function foo1(){    return {      bar: "hello"    };}function foo2(){    return    {      bar: "hello"    };}

令人惊讶的是,这两个函数不会返回相同的结果。而是:

console.log("foo1 returns:");console.log(foo1());console.log("foo2 returns:");console.log(foo2());

会产生:

foo1 returns:{bar: "hello"}foo2 returns:undefined

这不仅令人惊讶,而且特别令人烦恼的是,foo2()返回未定义而没有引发任何错误。

起因与JavaScript中分号在技术上是可选的事实有关(虽然忽略它们通常是非常糟糕的形式)。因而,在foo2()中遇到包含return语句的行(没有其余内容)时,会在return语句之后立即自动插入分号。

因为代码的其他部分是完全有效的,即便它没有被调用或者做任何事情(它只是一个未使用的代码块,它定义了一个属性栏,它等于字符串“hello”),所以不会抛出任何错误。

这种行为也被认为是遵循了在JavaScript中将一行开头大括号放在行尾的商定,而不是在新行的开头。如此处所示,这不仅仅是JavaScript中的一种风格偏好。

7、什么是NaN?它的类型是什么?如何可靠地测试一个值能否等于NaN?

NaN属性表示“不是数字”的值, 这个特殊值是因为一个操作是非数字的(例如 “abc”/4) 或者者由于操作的结果是非数组而无法执行的

尽管这看起来很简单,但是NaN有少量令人惊讶的特征,假如开发者们没有意识到这些特征,就会导致bug

尽管NaN的意思是“不是数字”,但它的类型是数字:

console.log(typeof NaN === "number"); // true

此外,NaN相比任何事情,甚至本身 都是false

console.log(NaN === NaN)

测试数字能否等于NaN的半可靠方法是使用内置函数isNaN(),但即便使用isNaN()也不是一个好的处理方案。.

一个更好的处理方案要么是使用value!==值,假如该值等于NaN,那么只会生成true。另外,ES6提供了一个新的Number.isNaN()函数 ,它与旧的全局isNaN()函数不同,也更加可靠。

8、下面的代码输出什么?解释你的答案。

console.log(0.1 + 0.2);console.log(0.1 + 0.2 == 0.3);

对这个问题的一个有教养的答复是 :”不能确定,它可能打印0.3 和 true ,或者者可能不打印,JavaScript中数字一律用浮点精度解决,因而可能不会总是产生预期结果

上面提供的示例是演示此问题的经典案例。令人惊讶的是,它会打印出来:

0.30000000000000004false

一个典型的处理方案是比较两个数组与特殊常数Number.EPSILON的绝对差值

function areTheNumbersAlmostEqual(num1, num2) {  return Math.abs(num1 - num2) < Number.EPSILON;}console.log(areTheNumbersAlmostEqual(0.1 + 0.2, 0.3));

9、执行下面的代码时,按什么顺序将数字1-4记录到控制台?为什么?

(function () {  console.log(1);  setTimeout(function () {    console.log(2);  }, 1000);  setTimeout(function () {    console.log(3);  }, 1000);  console.log(4);});

这些值将按以下顺序记录:

1432

我们先来解释一下这些可能更为显著的部分:

首先显示1和4,由于它们是通过简单调用console.log()而没有任何推迟记录的

在3之后显示,由于在推迟1000毫秒(即1秒)之后记录2,而在0毫秒的推迟之后记录3。

但是,假如在推迟0毫秒后记录3,这能否意味着它正在被立即记录?而且,假如是这样,不应该在4之前记录它,由于4是由后面的代码行记录的吗?

答案与正确了解JavaScript事件和时间有关。 .

浏览器有一个事件循环,它检查事件队列并解决未决事件。例如,假如在浏览器繁忙时(例如,解决onclick)在后端发生事件(例如脚本onload事件),则该事件被附加到队列中。当onclick解决程序完成时,将检查队列并解决该事件(例如,执行onload脚本)。

同样,假如浏览器繁忙,setTimeout()也会将其引用函数的执行放入事件队列中。

当值为零作为setTimeout()的第二个参数传递时,它将尝试“尽快”执行指定的函数。具体来说,函数的执行放置在事件队列中,以在下一个计时器滴答时发生。但请注意,这不是直接的;该功能不会执行,直到下一个滴答声。这就是为什么在上面的例子中,调用console.log(4)发生在调用console.log(3)之前(由于调用console.log(3)是通过setTimeout调用的,所以略微推迟了一点)。

10、编写一个简单的函数(少于160个字符),返回一个布尔值,指示字符串能否是palindrome。

function isPalindrome(str) {  let a = str.replace(/\W/g, "");  console.log(a);  str = a.toLowerCase();  return str == str.split("").reverse().join("");}

例如:

console.log(isPalindrome("level")); // trueconsole.log(isPalindrome("levels")); // falseconsole.log(isPalindrome("A car, a man, a maraca")); // true
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » js常见面试题(一)

发表回复