美文网首页饥人谷技术博客
我错过的JS面试题,你别再错了。

我错过的JS面试题,你别再错了。

作者: fejavu | 来源:发表于2019-10-08 00:51 被阅读0次

    这段时间在进行 web 前端的面试,在各大平台、社区寻找面试题,其中有一些基础的面试题,用来检查自己的基础的地方。

    掘金上的 Cornad Li 将Github的一个很火的基础题翻译过来,自己试着做了一下,还是错了不少,有些是基础不牢,有些是粗心,用错题集整理一下,查漏补缺。

    1. global / window变量声明

    下面代码会输出什么?

    let greeting = "Halo";
    greating = "Fuck JavaScript";
    console.log(greating);
    

    浏览器中当没有声明变量时(使用let const var等),会自动将变量声明为window/global的一个属性,并完成赋值,因此输出是:
    "Fuck JavaScript"

    1. 当我们这样做时会发生什么?
    function bark() {
      console.log("Woof!");
    }
    bark.animal = "dog";
    

    A: Nothing, this is totally fine!
    B: SyntaxError. You cannot add properties to a function this way.
    C: undefined
    D: ReferenceError
    答案:A。因为在JavaScript中,函数也是一种对象,因此可以对其添加属性并赋值。

    1. 构造函数属性的添加

    下面代码的输出是什么?

    function Person(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }
    
    const member = new Person("Lydia", "Hallie");
    Person.getFullName = () => this.firstName + this.lastName;
    
    console.log(member.getFullName());
    

    A: TypeError
    B: SyntaxError
    C: Lydia Hallie
    D: undefined undefined
    答案:A。构造函数添加属性,不能像一般对象那样直接添加,而是要在构造函数的原型上添加属性。像这样:

    Person.prototype.getFullName = function() {
      return  this.firstName+this.lastName;
    }
    
    1. this值 / new操作符流程

    下面代码输出是什么?

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

    A. undefined
    B. ReferenceError
    C. {}
    D. Person {firstName: "Sarah", lastName: "Smith"}
    答案:A。由于lydia定义时 使用new关键词,因此lydia定义时的构造函数Person中的this是指lydia,而sarah定义时未使用关键词,因此构造函数中的this是定义的,也就是undefined,在非严格模式下,构造函数中的this就是window,因此window.firstNamewindow.lastName就是undefined
    PS:在严格模式下,下面中会直接报错:Cannot set property 'firstName' of undefined

    function Person(firstName, lastName) {
      "use strict";
      this.firstName = firstName;
      this.lastName = lastName;
      console.log(this);
    }
    
    const lydia = new Person("Lydia", "Hallie");
    const sarah = Person("Sarah", "Smith");
    /*  
    [object Object] {
      firstName: "Lydia",
      lastName: "Hallie"
    }  // lydia
    
    "TypeError: Cannot set property 'firstName' of undefined  // sarah
    */
    
    1. 自加自减运算
    let number = 0;
    console.log(number++);
    console.log(++number);
    console.log(number);
    

    A: 1 1 2
    B: 1 2 2
    C: 0 2 2
    D: 0 1 2
    答案: C。
    后缀一元运算符++: 返回值 0,增加值 1
    前缀一元运算符++: 增加值 2,返回值 2
    MDN-Expressions_and_Operators

    1. 带标签的模板字符串

    以下代码输出什么?

    function getPersonInfo(one, two, three) {
      console.log(one);
      console.log(two);
      console.log(three);
    }
    const person = "Lydia";
    const age = 21;
    getPersonInfo`${person} is ${age} years old`;
    

    A: Lydia 21 ["", "is", "years old"]
    B: ["", "is", "years old"] Lydia 21
    C: Lydia ["", "is", "years old"] 21
    答案:B。带标签的模板字符串第一个参数包含一个字符串值的数组,其余参数与表达式相关。因此two, three分别是${person}, ${age}

    1. 基础类型和引用类型区别

    以下代码输出什么?

    function checkAge(data) {
      if (data === { age: 18 }) {
        console.log("You are an adult!");
      } else if (data == { age: 18 }) {
        console.log("You are still an adult.");
      } else {
        console.log(`Hmm.. You don't have an age I guess`);
      }
    }
    checkAge({ age: 18 });
    

    A: You are an adult!
    B: You are still an adult.
    C: Hmm.. You don't have an age I guess
    答案: C。涉及到基础类型和引用类型的比较。原始类型通过值去比较,只要值相等,两个就相等。而引用类型(对象)通过他们的引用的内存地址是否一样去比较相似性。JavaScript检查对象是否具有对内存中相同位置的引用。这就是为什么{ age: 18 } === { age: 18 }和 { age: 18 } == { age: 18 } 返回 false的原因。

    1. 拓展运算符
      以下代码输出什么?
    function getAge(...args) {
      console.log(typeof args);
    }
    getAge(21);
    

    A: "number"
    B: "array"
    C: "object"
    D: "NaN"
    答案:C。扩展运算符(... args)返回一个带参数的数组。 数组是一个对象,因此typeof args返回object。

    1. 严格模式下的引用错误。
    function getAge() {
      "use strict";
      age = 21;
      console.log(age);
    }
    getAge();
    

    A: 21
    B: undefined
    C: ReferenceError
    D: TypeError
    答案:C。使用严格模式"use strict";可以确保不会意外地生成全局变量,我们从未声明变量age,因为我们使用``use strict',它会引发一个ReferenceError。 如果我们不使用“use strict”,它就会起作用,因为属性age`会被添加到全局对象中。

    1. sessionStorage, localStorage

    cool_secret可以访问多长时间?

    sessionStorage.setItem("cool_secret", 123);
    

    A:永远,数据不会丢失。
    B:用户关闭选项卡时。
    C:当用户关闭整个浏览器时,不仅是选项卡。
    D:用户关闭计算机时。
    答案: B。
    关闭选项卡后,将删除存储在sessionStorage中的数据。如果使用localStorage,数据将永远存在,除非例如调localStorage.clear()
    MDN-sessionStorage
    MDN-localStorage

    1. continue关键字

    下面代码的输出是什么?

    for (let i = 1; i < 5; i++) {
      if (i === 3) continue;
      console.log(i);
    }
    

    A: 1 2
    B: 1 2 3
    C: 1 2 4
    D: 1 3 4
    答案: C。
    如果某个条件返回true,则continue语句跳过迭代。

    1. 基本类型的装箱转换

    下面代码的输出是什么?

    String.prototype.giveLydiaPizza = () => {
      return "Just give Lydia pizza already!";
    };
    const name = "Lydia";
    name.giveLydiaPizza();
    

    A: "Just give Lydia pizza already!"
    B: TypeError: not a function
    C: SyntaxError
    D: undefined
    答案: A。
    String是一个内置的构造函数,我们可以为它添加属性。 我刚给它的原型添加了一个方法。 原始类型的字符串自动转换为字符串对象,由字符串原型函数生成。 因此,所有字符串(字符串对象)都可以访问该方法!
    译者ConardLi 注:
    当使用基本类型的字符串调用giveLydiaPizza时,实际上发生了下面的过程:

    • 创建一个String的包装类型实例
    • 在实例上调用substring方法
    • 销毁实例

    学习者注:也就是基础类型转化为引用类型的 "装箱转换",这使得基础类型例如string, number, boolean 的变量可以调用其对应复杂类型对象上的方法。

    1. 对象键值自动转化为字符串。

    下面代码的输出是什么?

    const a = {};
    const b = { key: "b" };
    const c = { key: "c" };
    a[b] = 123;
    a[c] = 456;
    console.log(a[b]);
    

    A: 123
    B: 456
    C: undefined
    D: ReferenceError
    答案: B
    对象键自动转换为字符串。我们试图将一个对象设置为对象a的键,其值为123。
    但是,当对象自动转换为字符串化时,它变成了[Object object]。 所以我们在这里说的是a["Object object"] = 123。 然后,我们可以尝试再次做同样的事情。 c对象同样会发生隐式类型转换。那么,a["Object object"] = 456。
    然后,我们打印a[b],它实际上是a["Object object"]。 我们将其设置为456,因此返回456。
    此时打印出a, b, c分别是:

    [object Object] {
      [object Object]: 456
    }  // a
    [object Object] {
      key: "b"
    }  // b
    [object Object] {
      key: "c"
    }  // c
    
    1. 单击按钮时event.target是什么?
    <div onclick="console.log('first div')">
      <div onclick="console.log('second div')">
        <button onclick="console.log('button')">
          Click!
        </button>
      </div>
    </div>
    

    A: div外部
    B: div内部
    C: button
    D: 所有嵌套元素的数组.
    答案: C。
    导致事件的最深嵌套元素是事件的目标。 可以通过在需要停止冒泡的地方用 event.stopPropagation 停止冒泡。

    document.querySelector('button').addEventListener('click', event=> {
      event.stopPropagation();
      console.log(event.target);
    });
    /* 
    button   
    <button onclick="console.log('button')">Click!
    </button>
    */
    
    1. 块级作用域。

    下面代码的输出是什么?

    (() => {
      let x, y;
      try {
        throw new Error();
      } catch (x) {
        (x = 1), (y = 2);
        console.log(x);
      }
      console.log(x);
      console.log(y);
    })();
    

    A: 1 undefined 2
    B: undefined undefined undefined
    C: 1 1 2
    D: 1 undefined undefined
    答案: A。
    catch作用域中的x与外面的x不同,不是同一个x
    catch中的赋值,对catch外的x没有作用,对y有作用,因为y的赋值是catch在作用域链上对外部y的赋值。
    x还是undefinedy被赋值为2。

    1. JavaScript中的所有内容都是...

    A:原始或对象
    B:函数或对象
    C:技巧问题!只有对象
    D:数字或对象
    答案: A
    JavaScript只有原始类型和对象。
    原始类型是boolean,null,undefined,bigint,number,string和symbol

    1. JavaScript单变量的布尔值转换

    下面代码的输出是什么?

    !!null;
    !!"";
    !!1;
    

    A: false true false
    B: false false true
    C: false true true
    D: true true false
    答案: B
    null是假值。 !null返回true!true返回false
    ""是假值。 !""返回true!true返回false
    1是真值。 !1返回false!false返回true
    学习者注:JavaScript的单变量布尔值的转化中,以下几种为false,其余为truenull, undefined, '', NaN, 0,false

    相关文章

      网友评论

        本文标题:我错过的JS面试题,你别再错了。

        本文链接:https://www.haomeiwen.com/subject/dgpppctx.html