值得收藏的几道JavaScript面试题

1、下面的代码的输出是什么?

function sayHi() {
        console.log(name);       //undefined
        console.log(age);
        var name = "JiaoMaiQi";      //ReferenceError
        let age = 23;
    }
    sayHi();

解析:在函数中,我们首先使用了var关键字声明了name变量。这意味着变量在创建阶段会被提升,即var name会被分配内存空间,而赋值是在执行阶段进行。因此name变量提升之后,默认值为undefined。而let关键字声明变量也会存在变量提升,但是与var不同,初始化没有被提升。在我们声明(初始化)他们之前,他们是不可访问的。这被称之为“暂时性死区”。因此,当我们访问未声明的变量时,JavaScript就会抛出一个ReferenceError。

        关于let是否存在变量提升,我们先看一个例子:

 let name = 'JiaoMaiQi';
    {
        console.log(name);
        let name = 'YangNan';
    }

      倘若let变量不存在变量提升,console.log(name)就会输出‘JiaoMaiQi’,结果却抛出了异常。因此,这很好的说明了,let也存在变量提升,但是它存在一个暂时性死区,在变量未初始化或赋值之前不允许访问。

     变量的赋值可以分为三个阶段:

  • 创建变量,在内存中开辟空间
  • 初始化变量,将变量初始化为undefined
  • 真正赋值

   关于let、var和function:

  • let的【创建】过程被提升了,但是【初始化】没有提升
  • var 的【创建】和【初始化】都被提升了
  • function 的【创建】和【初始化】和【赋值】都被提升了

2、下面代码输出什么?

for(var i = 0; i<3;i++){
        setTimeout(() => console.log(i),1);     //3,3,3
    }
    for(let i = 0; i < 3; i++){
        setTimeout(() => console.log(i),1)      //0,1,2
    }

  解析:由于JavaScript中的事件执行机制,setTimeout()函数被真正执行的时候,循环已经走完。由于第一个循环变量i是用var关键字声明的,因此该值是全局的。因此在第一个循环例子中当调用setTimeout函数时,i已经被赋值为3。

            在第二个循环中,i是let关键字声明的:使用let和const关键字声明是具有块级作用域的。因此,在每次迭代期间,i将被创建为一个新的值,并且每个值都会存在于循环内的块级作用域。

3、下面的代码输出是什么?

const shape = {
       radius: 10,
       diameter() {
           return this.radius * 2;
       },
       perimeter: () => 2*Math.PI*this.radius
   };
   console.log(shape.diameter());
   console.log(shape.perimeter());

    

      解析:diameter是普通函数而perimeter是箭头函数。对于箭头函数,this关键字指向的是他的上下文(定义时的环境),与普通函数不同。这意味着当我们调用perimeter时,它不是指向shape对象,而是指向其定义时的环境(window)。因window并没有radius属性,因此返回undefined。

4、下面代码输出什么?

 console.log(+true);
   console.log(!"Lucy");

    

解析:一元加号会尝试将boolean类型转换为数字类型。true转换为1,false转换为0。字符串'Lucy'是一个真值。我们实际上要问的是“这个真值是假的吗?”。这会返回false。

5、下面代码输出什么?

let a = { hello: "word"};
   let b;
   b = a;
   a.hello = "China";
   console.log(b.hello);

    

解析:在JS中,当设置他们彼此相等时,所有对象都通过引用进行交互。首先变量a为对象保存一个值,之后,我们将b指定为a与对象相同的引用。更改一个对象时,可以更改所有对象。

6、下面代码的输出是什么?

let a = 4;
   let b = new Number(4);
   let c = 4;
   console.log(a==b);      //true
   console.log(b===c);     //false
   console.log(a===c);     //true

 

解析:new Number()是一个内置的函数构造函数。虽然它看起来像一个数字,但它并不是一个真正的数字:它有一对额外的功能,是一个对象。当我们使用“==”运算符时,它只检查它是否具有相同的值。他们都有4这个值,所以它返回true。当使用“===”操作符时,类型和值都需要相等,new number()不是一个数字,是一个对象类型。两者都返回false。

7、下面代码的输出是什么?

let greeting;
   greetign = {};
   console.log(greetign);

   

解析:控制台如上图所示会输出空对象,因为我们在全局对象上创建了一个空对象!当我们错误的将greeting输入为greetign时,js解释器实际上在浏览器中将其视为global.greetign = {}(或window.greetign = {})。因此,为了避免这种情况出现,我们可以使用“use strict”。这可以确保在变量赋值之前必须先声明变量。

8、当我们这样做的时候会发生什么?

function bark() {
       console.log("woof");
   }
   bark.animal = "dog";

解析:此函数所含有的属性可以调用,不过该段代码不会输出什么,但也不会报错。

9、下面代码会输出什么?

 function Person(firstName, lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }
   const  lydia = new  Person("Lydia","Hallie");
   const sarah = Person("Sarah","Smith");
   console.log(lydia);
   console.log(sarah);

    

解析:对于sarah,我们没有使用new关键字。使用new时,它指的是我们创建的新空对象。但是,如果你不添加new它指的是全局对象。因此,我们指定的this.firstName等于'Sarah'和this.lastName等于'Smith'。实际上定义的是global.firstName = 'Sarah'和global.lastName = 'Smith'。sarah本身的返回值是undefined。

10、下面代码的输出是什么?

let number = 0;
   console.log(number++);
   console.log(++number);
   console.log(number);

  

解析:后缀一元运算符++:

           1、返回值(返回0)

           2、增加值(数字现在是1)

           前缀一元运算符++:

           1、增加值(数字现在是2)

           2、返回值(返回2)

11、下面代码输出什么?

 function getAge(...args) {
       console.log(typeof args);
   }
   getAge(22);

     

解析:扩展运算符(...args)返回一个带参数的数组。数组是一个对象,因此typeof args返回object。

12、下面代码输出什么?

 function getAge( ) {
       "use strict";
       age = 21;
       console.log(age);
   }

解析:会报错ReferenceError。使用"use strict",可以确保不会意外的声明全局变量。我们从未声明变量age,因此我们使用"use strict",它会引发一个ReferenceError。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值