好程序员Java教程分享JavaScript常见面试题二:1.在JavaScript源文件的开头包含 use strict 有什么意义和好处?程序员
对于这个问题,既简要又最重要的答案是,use strict 是一种在JavaScript代码运行时自动实行更严格解析和错误处理的方法。那些被忽略或默默失败了的代码错误,会产生错误或抛出异常。一般而言,这是一个很好的作法。面试
严格模式的一些主要优势包括:编程
使调试更加容易。那些被忽略或默默失败了的代码错误,会产生错误或抛出异常,所以尽早提醒你代码中的问题,你才能更快地指引到它们的源代码。安全
防止意外的全局变量。若是没有严格模式,将值分配给一个未声明的变量会自动建立该名称的全局变量。这是JavaScript中最多见的错误之一。在严格模式下,这样作的话会抛出错误。ide
消除 this 强制。若是没有严格模式,引用null或未定义的值到 this 值会自动强制到全局变量。这可能会致使许多使人头痛的问题和让人巴不得拔本身头发的bug。在严格模式下,引用 null或未定义的 this 值会抛出错误。函数
不容许重复的属性名称或参数值。当检测到对象(例如,var object = {foo: "bar", foo: "baz"};)中重复命名的属性,或检测到函数中(例如,function foo(val1, val2, val1){})重复命名的参数时,严格模式会抛出错误,所以捕捉几乎能够确定是代码中的bug能够避免浪费大量的跟踪时间。测试
使eval() 更安全。在严格模式和非严格模式下,eval() 的行为方式有所不一样。最显而易见的是,在严格模式下,变量和声明在 eval() 语句内部的函数不会在包含范围内建立(它们会在非严格模式下的包含范围中被建立,这也是一个常见的问题源)。this
在 delete使用无效时抛出错误。delete操做符(用于从对象中删除属性)不能用在对象不可配置的属性上。当试图删除一个不可配置的属性时,非严格代码将默默地失败,而严格模式将在这样的状况下抛出异常。spa
2.考虑如下两个函数。它们会返回相同的东西吗? 为何相同或为何不相同?调试
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:Object {bar: "hello"}foo2 returns:undefined
这不只是使人惊讶,并且特别让人困惑的是, foo2()返回undefined却没有任何错误抛出。
缘由与这样一个事实有关,即分号在JavaScript中是一个可选项(尽管省略它们一般是很是糟糕的形式)。其结果就是,当碰到 foo2()中包含 return语句的代码行(代码行上没有其余任何代码),分号会当即自动插入到返回语句以后。
也不会抛出错误,由于代码的其他部分是彻底有效的,即便它没有获得调用或作任何事情(至关于它就是是一个未使用的代码块,定义了等同于字符串 "hello"的属性 bar)。
这种行为也支持放置左括号于JavaScript代码行的末尾,而不是新代码行开头的约定。正如这里所示,这不只仅只是JavaScript中的一个风格偏好。
3. NaN 是什么?它的类型是什么?你如何可靠地测试一个值是否等于 NaN ?
NaN 属性表明一个“不是数字”的值。这个特殊的值是由于运算不能执行而致使的,不能执行的缘由要么是由于其中的运算对象之一非数字(例如, "abc" / 4),要么是由于运算的结果非数字(例如,除数为零)。
虽然这看上去很简单,但 NaN 有一些使人惊讶的特色,若是你不知道它们的话,可能会致使使人头痛的bug。
首先,虽然 NaN 意味着“不是数字”,可是它的类型,无论你信不信,是 Number:
console.log(typeof NaN === "number"); // logs "true"
此外, NaN 和任何东西比较——甚至是它本身自己!——结果是false:
console.log(NaN === NaN); // logs "false"
一种半可靠的方法来测试一个数字是否等于 NaN,是使用内置函数 isNaN(),但即便使用 isNaN() 依然并不是是一个完美的解决方案。
一个更好的解决办法是使用 value !== value,若是值等于NaN,只会产生true。另外,ES6提供了一个新的 Number.isNaN() 函数,这是一个不一样的函数,而且比老的全局 isNaN() 函数更可靠。
4.下列代码将输出什么?并解释缘由。
console.log(0.1 + 0.2);console.log(0.1 + 0.2 == 0.3);
一个稍微有点编程基础的回答是:“你不能肯定。可能会输出“0.3”和“true”,也可能不会。JavaScript中的数字和浮点精度的处理相同,所以,可能不会老是产生预期的结果。“
以上所提供的例子就是一个演示了这个问题的典型例子。但出人意料的是,它会输出:
0.30000000000000004false
5.讨论写函数 isInteger(x) 的可能方法,用于肯定x是不是整数。
这可能听起来是小菜一碟,但事实上,这很琐碎,由于ECMAScript 6引入了一个新的正以此为目的 Number.isInteger() 函数。然而,以前的ECMAScript 6,会更复杂一点,由于没有提供相似的 Number.isInteger() 方法。
问题是,在ECMAScript规格说明中,整数只概念上存在:即,数字值老是存储为浮点值。
考虑到这一点,最简单又最干净的ECMAScript6以前的解决方法(同时也很是稳健地返回 false ,即便一个非数字的值,如字符串或 null ,被传递给函数)以下:
function isInteger(x) { return (x^0) === x; }
下面的解决方法也是可行的,虽然不如上面那个方法优雅:
function isInteger(x) { return Math.round(x) === x; }
请注意 Math.ceil() 和 Math.floor() 在上面的实现中等同于 Math.round()。
或:
function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0);
至关广泛的一个不正确的解决方案是:
function isInteger(x) { return parseInt(x, 10) === x; }
虽然这个以 parseInt函数为基础的方法在 x 取许多值时都能工做良好,但一旦 x 取值至关大的时候,就会没法正常工做。问题在于 parseInt() 在解析数字以前强制其第一个参数到字符串。所以,一旦数目变得足够大,它的字符串就会表达为指数形式(例如, 1e+21)。所以,parseInt() 函数就会去解析 1e+21,但当到达 e字符串的时候,就会中止解析,所以只会返回值 1。注意:
> String(1000000000000000000000)'1e+21'> parseInt(1000000000000000000000, 10)1> parseInt(1000000000000000000000, 10) === 1000000000000000000000false