这段时间在进行 web 前端的面试,在各大平台、社区寻找面试题,其中有一些基础的面试题,用来检查自己的基础的地方。
掘金上的 Cornad Li 将Github
的一个很火的基础题翻译过来,自己试着做了一下,还是错了不少,有些是基础不牢,有些是粗心,用错题集整理一下,查漏补缺。
- global / window变量声明
下面代码会输出什么?
let greeting = "Halo";
greating = "Fuck JavaScript";
console.log(greating);
浏览器中当没有声明变量时(使用let const var
等),会自动将变量声明为window/global
的一个属性,并完成赋值,因此输出是:
"Fuck JavaScript"
- 当我们这样做时会发生什么?
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中,函数也是一种对象,因此可以对其添加属性并赋值。
- 构造函数属性的添加
下面代码的输出是什么?
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;
}
- 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.firstName
和window.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
*/
- 自加自减运算
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
- 带标签的模板字符串
以下代码输出什么?
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}
。
- 基础类型和引用类型区别
以下代码输出什么?
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的原因。
- 拓展运算符
以下代码输出什么?
function getAge(...args) {
console.log(typeof args);
}
getAge(21);
A: "number"
B: "array"
C: "object"
D: "NaN"
答案:C。扩展运算符(... args)返回一个带参数的数组。 数组是一个对象,因此typeof args返回object。
- 严格模式下的引用错误。
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`会被添加到全局对象中。
- sessionStorage, localStorage
cool_secret可以访问多长时间?
sessionStorage.setItem("cool_secret", 123);
A:永远,数据不会丢失。
B:用户关闭选项卡时。
C:当用户关闭整个浏览器时,不仅是选项卡。
D:用户关闭计算机时。
答案: B。
关闭选项卡后,将删除存储在sessionStorage
中的数据。如果使用localStorage
,数据将永远存在,除非例如调localStorage.clear()
。
MDN-sessionStorage
MDN-localStorage
-
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语句跳过迭代。
- 基本类型的装箱转换
下面代码的输出是什么?
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 的变量可以调用其对应复杂类型对象上的方法。
- 对象键值自动转化为字符串。
下面代码的输出是什么?
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
- 单击按钮时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>
*/
- 块级作用域。
下面代码的输出是什么?
(() => {
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
还是undefined
,y
被赋值为2。
-
JavaScript
中的所有内容都是...
A:原始或对象
B:函数或对象
C:技巧问题!只有对象
D:数字或对象
答案: A
JavaScript
只有原始类型和对象。
原始类型是boolean,null,undefined,bigint,number,string和symbol
。
-
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
,其余为true
,null, undefined, '', NaN, 0,false
。
网友评论