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

这段时间在进行 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是什么?

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

document.querySelector('button').addEventListener('click', event=> {
  event.stopPropagation();
  console.log(event.target);
});
/* 
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

  • 参考阅读
    [译] 送你 43 道 JavaScript 面试题,ConardLi。

你可能感兴趣的:(我错过的JS面试题,你别再错了。)