js里的那些常见的面试题

嗨喽码农们:
又见面了,继上次分享的面试题,今天再为大家分享一些关于js 那些面试常见的问题。希望对大家有帮助,喜欢的可以点赞收藏起来。

五、小心javascript自动插入分号机制
在《JavaScript语言精粹》这本书里,这个“自动插入分号”机制被划入到了JavaScript的毒瘤里面,与之并列的前面的全局变量。
有些时候,不合时宜地插入分号,会导致严重的后果。 比如一个return语句要正确返回一个值,这个值的表达式的开始部分必须和return位于同一行。
今天,我们就来聊聊这个知识点,看下面的代码函数,它们会返回什么?

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,也没有任何错误抛出。

原因是这样的,当碰到 foo2()中包含return语句的代码行(代码行上没有其他任何代码),分号会立即自动插入到返回语句之后。请仔细留意上面两个函数中return的不同之处,foo2函数的return是单独一行的。

也不会抛出错误,因为代码的其余部分是完全有效的,即使它没有得到调用或做任何事情(相当于它就是是一个未使用的代码块,定义了等同于字符串 "hello"的属性 bar)。

所以,在使用return语句的时候,要留意javascript的这个特点,尽可能不要将return关键字写在独立的一行,避免不必造成不必要的错误。

六、NaN 是什么?如何测试一个值是否等于 NaN ?

NaN 这个知识点的问题在《趣味ES6》的系列很多人留言说觉得很绕,不好理解,的确,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。因为只有NaN 这货,才会自己不等于自己。

另外,ES6提供了一个新的 Number.isNaN() 函数,这是一个不同的函数,并且比老的全局 isNaN() 函数更可靠。

七、下面的代码运行结果是什么?
例子1:

console.log(1 +  "2" + "2");

得到的结果是:“122”;
解析: 1 + “2” + “2” 输出: “122” 。 1 + “2” 是执行的第一个操作。由于其中一个运算对象 “2” 是字符串,JavaScript会假设它需要执行字符串连接,因此,会将 1 的类转换为 “1” , 1+“2” 结果就是 “12” 。然后, “12”+“2” 就是 “122” 。

例子2:

console.log(1 +  +"2" + "2");

得到的结果是:“32”;
解析: 1 + +“2” + “2” 输出: “32” 说明:根据运算的顺序,要执行的第一个运算是 +“2” (第一个 “2” 前面的额外 + 被视为一元运算符)。

因此,JavaScript将 “2” 的类型转换为数字,然后应用一元 + 号(即将其视为一个正数)。其结果就是得到一个数字 2 ,接下来的运算就是 1 + 2 ,这当然是 3 。

然后我们需要在一个数字和一个字符串之间进行运算(即, 3 和 “2”),同样的,JavaScript会将数值类型转换为字符串,并执行字符串的连接,产生 “32” 。

例子3:

console.log(1 +  -"1" + "2");

得到的结果是:“02”;
解析: 1 + -“1” + “2” 输出: “02” 。这里的解释和前一个例子相同,不同的地方是此处的一元运算符是 - 而不是 + 。

先是 “1” 变为 1 ,然后当应用 - 时又变为了 -1 ,然后将其与 1 相加,结果为 0 ,再将其转换为字符串,连接最后的 “2” 运算对象,得到 “02” 。

例子4:

console.log(+"1" +  "1" + "2");

得到的结果是:“112”;
解析: +“1” + “1” + “2” 输出: “112” 。虽然第一个运算对象 “1” 因为前缀的一元 + 运算符类型转换为数值,但当连接到第二个运算对象 “1” 的时候,又立即转换回字符串,然后又和最后的运算对象 “2” 连接,产生了字符串 “112” 。

例子5:

console.log( "A" - "B" + "2");

得到的结果是:“NaN2”;
解析: “A” - “B” + “2” 输出: “NaN2” 。由于运算符 - 不能被应用于字符串,并且 “A” 和 “B” 都不能转换成数值,因此, “A” - “B” 的结果是 NaN ,然后再和字符串 “2” 连接,得到 “NaN2” 。

例子6:

console.log( "A" - "B" + 2);

得到的结果是:NaN;
解析: “A” - “B” + 2 输出: NaN 。参见前一个例子, “A” - “B” 结果为 NaN 。但是,应用任何运算符到 NaN 与其他任何的数字运算对象,结果仍然是 NaN 。

八、关于逻辑运算符,下面代码运行的结果是什么?

逻辑运算符用于测定变量或值之间的逻辑。在我们实际开发过程中十分常用,所以面试官会把逻辑运算符的知识点当作考察应聘者的内容之一。

在JavaScript中, || 和 && 都是逻辑运算符,用于在从左至右计算时,返回第一个可完全确定的“逻辑值”。

讲解
或 || 运算符。在 X||Y 的表达式中,首先计算 X 并将其解释执行为一个布尔值。

如果这个布尔值true,那么返回true(1),不再计算 Y ,因为“或”的条件已经满足。

如果这个布尔值为false,那么我们仍然不能知道 X||Y 是真是假,直到我们计算 Y ,并且也把它解释执行为一个布尔值。

因此, 0||1 的计算结果为true(1),同理计算 1||2 。

与 && 运算符。在 X&&Y 的表达式中,首先计算 X 并将其解释执行为一个布尔值。

如果这个布尔值为 false,那么返回 false(0),不再计算 Y ,因为“与”的条件已经失败。

如果这个布尔值为true,但是,我们仍然不知道 X&&Y 是真是假,直到我们去计算 Y ,并且也把它解释执行为一个布尔值。 .

不过,关于 && 运算符有趣的地方在于,当一个表达式计算为“true”的时候,那么就返回表达式本身。

这很好,虽然它在逻辑表达式方面计算为“真”,但如果你希望的话也可用于返回该值。这就解释了为什么,有些令人奇怪的是, 1 && 2返回 2,而不是你以为的可能返回 true 或 1。

看完了讲解,大家可以试一下解答这个例子。

题目:


console.log( 0 || 1 );
console.log( 1 || 2 );
console.log( 0 && 1 );
console.log( 1 && 2 );

他们运行的结果是什么,在底下留言写下你的答案!

九、以下代码将输出什么?并解释你的答案。
看下面的代码,输出的结果是什么?并解释你的答案。

var a={},
    b={key:'b'},   
    c={key:'c'};

a[b]=123;
a[c]=456;

console.log(a[b]);

不少人可能会以为答案是 123 ,但结果是 456 ,为什么会是这样子的呢。

原因是我们忽略了一个知识点:JavaScript在设置对象的属性的时候,会暗中字符串化参数值。

在这里例子中,由于 b 和 c都是对象,把它们设置为对象a的参数,它们都将被转换为 “[object Object]” 。

结果就是, a[b] 和 a[c] 都相当 “[object Object]” ,而后者会将前者的值覆盖。

因此,设置或引用 a[c] 和设置或引用 a[b] 完全相同。所以得到的答案是 456 。

十、关于this指向,以下代码将输出什么?
var person = {
_name: ‘I am John’,
sayHello: function (){
return this._name;
}
};

var sayHello = person.sayHello;

console.log(sayHello());
console.log(person.sayHello());

var person = {
    _name: 'I am John',
    sayHello: function (){        
        return this._name;
    }
};
        
var sayHello = person.sayHello;

console.log(sayHello());
console.log(person.sayHello());

代码运行的结果是:

undefined
I am John

第二个打印 person.sayHello() 的结果是: I am John 这个好理解。

为什么第一次打印出来的结果是 undefined 呢?明明是直接赋值过去的呀。这里涉及到的知识点就是:this的指向。

在执行 sayHello() 的时候,当访问到 this._name 时,此时的this已经不再是 person 对象,而是全局窗口对象,也就是 widnow 对象。

与此同时, widnow 对象并不存在 _name 属性,所以返回的是 undefined 。

所以在笔试面试看到一些代码题目的时候,如果你看到了 this ,就要小心谨慎,很可能这里就是面试官要考(keng)察(ni)的地方。

今天分享到此,下次继续!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值