43 道检验基础的 JavaScript 面试题,一招教你看懂 Netty
C:
ReferenceError
D:
TypeError
答案: A
在JavaScript
中,当设置它们彼此相等时,所有对象都通过引用进行交互。
首先,变量c
为对象保存一个值。 之后,我们将d
指定为c
与对象相同的引用。
更改一个对象时,可以更改所有对象。
7. 下面代码的输出是什么?
let a = 3;
let b = new Number(3);
let c = 3;
console.log(a == b);
console.log(a === b);
console.log(b === c);
A:
true
false
true
B:
false
false
true
C:
true
false
false
D:
false
true
true
答案: C
new Number()
是一个内置的函数构造函数。 虽然它看起来像一个数字,但它并不是一个真正的数字:它有一堆额外的功能,是一个对象。
当我们使用==
运算符时,它只检查它是否具有相同的值。 他们都有3
的值,所以它返回true
。
译者注:
==
会引发隐式类型转换,右侧的对象类型会自动拆箱为Number
类型。
然而,当我们使用===
操作符时,类型和值都需要相等,new Number()
不是一个数字,是一个对象类型。两者都返回 false
。
8. 下面代码的输出是什么?
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor;
}
constructor({ newColor = "green" } = {}) {
this.newColor = newColor;
}
}
const freddie = new Chameleon({ newColor: "purple" });
freddie.colorChange("orange");
A:
orange
B:
purple
C:
green
D:
TypeError
答案: D
colorChange
方法是静态的。 静态方法仅在创建它们的构造函数中存在,并且不能传递给任何子级。 由于freddie
是一个子级对象,函数不会传递,所以在freddie
实例上不存在freddie
方法:抛出TypeError
。
9. 下面代码的输出是什么?
let greeting;
greetign = {}; // Typo!
console.log(greetign);
A:
{}
B:
ReferenceError: greetign is not defined
C:
undefined
答案: A
控制台会输出空对象,因为我们刚刚在全局对象上创建了一个空对象! 当我们错误地将greeting
输入为greetign
时,JS 解释器实际上在浏览器中将其视为global.greetign = {}
(或window.greetign = {}
)。
为了避免这种情况,我们可以使用“use strict”
。 这可以确保在将变量赋值之前必须声明变量。
10. 当我们这样做时会发生什么?
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
中是可能的,因为函数也是对象!(原始类型之外的所有东西都是对象)
函数是一种特殊类型的对象。您自己编写的代码并不是实际的函数。 该函数是具有属性的对象,此属性是可调用的。
11. 下面代码的输出是什么?
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}
;
}
这样会使member.getFullName()
是可用的,为什么样做是对的? 假设我们将此方法添加到构造函数本身。 也许不是每个Person
实例都需要这种方法。这会浪费大量内存空间,因为它们仍然具有该属性,这占用了每个实例的内存空间。 相反,如果我们只将它添加到原型中,我们只需将它放在内存中的一个位置,但它们都可以访问它!
12. 下面代码的输出是什么?
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);
A:
Person {firstName: "Lydia", lastName: "Hallie"}
andundefined
B:
Person {firstName: "Lydia", lastName: "Hallie"}
andPerson {firstName: "Sarah", lastName: "Smith"}
C:
Person {firstName: "Lydia", lastName: "Hallie"}
and{}
D:
Person {firstName: "Lydia", lastName: "Hallie"}
andReferenceError
答案: A
对于sarah
,我们没有使用new
关键字。 使用new
时,它指的是我们创建的新空对象。 但是,如果你不添加new
它指的是全局对象!
我们指定了this.firstName
等于'Sarah
和this.lastName
等于Smith
。 我们实际做的是定义global.firstName ='Sarah'
和global.lastName ='Smith
。 sarah
本身的返回值是undefined
。
12. 事件传播的三个阶段是什么??
A: 目标 > 捕获 > 冒泡
B: 冒泡 > 目标 > 捕获
C: 目标 > 冒泡 > 捕获
D: 捕获 > 目标 > 冒泡
答案: D
在捕获阶段,事件通过父元素向下传递到目标元素。 然后它到达目标元素,冒泡开始。
13. 所有对象都有原型.
A: 对
B: 错误
答案: B
除基础对象外,所有对象都有原型。 基础对象可以访问某些方法和属性,例如.toString
。 这就是您可以使用内置JavaScript
方法的原因! 所有这些方法都可以在原型上找到。 虽然JavaScript
无法直接在您的对象上找到它,但它会沿着原型链向下寻找并在那里找到它,这使您可以访问它。
译者注:基础对象指原型链终点的对象。基础对象的原型是null
。
14. 下面代码的输出是什么?
function sum(a, b) {
return a + b;
}
sum(1, "2");
A:
NaN
B:
TypeError
C:
"12"
D:
3
答案: C
JavaScript
是一种动态类型语言:我们没有指定某些变量的类型。 在您不知情的情况下,值可以自动转换为另一种类型,称为隐式类型转换。 强制从一种类型转换为另一种类型。
在此示例中,JavaScript
将数字1
转换为字符串,以使函数有意义并返回值。 在让数字类型(1
)和字符串类型('2'
)相加时,该数字被视为字符串。 我们可以连接像“Hello”+“World”
这样的字符串,所以这里发生的是“1”+“2”
返回“12”
。
15. 下面代码的输出是什么?
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
)
所以返回0 2 2
。
16. 下面代码的输出是什么?
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
如果使用标记的模板字符串,则第一个参数的值始终是字符串值的数组。 其余参数获取传递到模板字符串中的表达式的值!
17. 下面代码的输出是什么?
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
的原因。
18. 下面代码的输出是什么?
function getAge(...args) {
console.log(typeof args);
}
getAge(21);
A:
"number"
B:
"array"
C:
"object"
D:
"NaN"
答案: C
扩展运算符(... args
)返回一个带参数的数组。 数组是一个对象,因此typeof args
返回object
。
20. 下面代码的输出是什么?
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
会被添加到全局对象中。
21. 下面代码的输出是什么?
const sum = eval("10*10+5");
A:
105
B:
"105"
C:
TypeError
D:
"10*10+5"
答案: A
eval
会为字符串传递的代码求值。 如果它是一个表达式,就像在这种情况下一样,它会计算表达式。 表达式为10 * 10 + 5
计算得到105
。
22. cool_secret 可以访问多长时间?
sessionStorage.setItem("cool_secret", 123);
A:永远,数据不会丢失。
B:用户关闭选项卡时。
C:当用户关闭整个浏览器时,不仅是选项卡。
D:用户关闭计算机时。
答案: B
关闭选项卡后,将删除存储在sessionStorage
中的数据。
如果使用localStorage
,数据将永远存在,除非例如调用localStorage.clear()
。
23. 下面代码的输出是什么?
var num = 8;
var num = 10;
console.log(num);
A:
8
B:
10
C:
SyntaxError
D:
ReferenceError
答案: B
使用var
关键字,您可以用相同的名称声明多个变量。然后变量将保存最新的值。
您不能使用let
或const
来实现这一点,因为它们是块作用域的。
24. 下面代码的输出是什么?
const obj = { 1: "a", 2: "b", 3: "c" };
const set = new Set([1, 2, 3, 4, 5]);
obj.hasOwnProperty("1");
obj.hasOwnProperty(1);
set.has("1");
set.has(1);
A:
false
true
false
true
B:
false
true
true
true
C:
true
true
false
true
D:
true
true
true
true
答案: C
所有对象键(不包括Symbols
)都会被存储为字符串,即使你没有给定字符串类型的键。 这就是为什么obj.hasOwnProperty('1')
也返回true
。
上面的说法不适用于Set
。 在我们的Set
中没有“1”
:set.has('1')
返回false
。 它有数字类型1
,set.has(1)
返回true
。
25. 下面代码的输出是什么?
const obj = { a: "one", b: "two", a: "three" };
console.log(obj);
A:
{ a: "one", b: "two" }
B:
{ b: "two", a: "three" }
C:
{ a: "three", b: "two" }
D:
SyntaxError
答案: C
如果对象有两个具有相同名称的键,则将替前面的键。它仍将处于第一个位置,但具有最后指定的值。
26. JavaScript 全局执行上下文为你创建了两个东西:全局对象和 this 关键字.
A: 对
B: 错误
C: 视情况而定
答案: A
基本执行上下文是全局执行上下文:它是代码中随处可访问的内容。
27. 下面代码的输出是什么?
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
语句跳过迭代。
28. 下面代码的输出是什么?
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
是一个内置的构造函数,我们可以为它添加属性。 我刚给它的原型添加了一个方法。 原始类型的字符串自动转换为字符串对象,由字符串原型函数生成。 因此,所有字符串(字符串对象)都可以访问该方法!
译者注:
当使用基本类型的字符串调用giveLydiaPizza
时,实际上发生了下面的过程:
创建一个
String
的包装类型实例在实例上调用
substring
方法销毁实例
29. 下面代码的输出是什么?
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
。
30. 下面代码的输出是什么?
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"));
const baz = () => console.log("Third");
bar();
foo();
baz();
A:
First
Second
Third
B:
First
Third
Second
C:
Second
First
Third
D:
Second
Third
First
答案: B
我们有一个setTimeout
函数并首先调用它。 然而却最后打印了它。
这是因为在浏览器中,我们不只有运行时引擎,我们还有一个叫做WebAPI
的东西。WebAPI
为我们提供了setTimeout
函数,例如DOM
。
将callback
推送到WebAPI
后,setTimeout
函数本身(但不是回调!)从堆栈中弹出。
现在,调用foo
,并打印First
。
foo
从堆栈弹出,baz
被调用,并打印Third
。
WebAPI
不能只是在准备就绪时将内容添加到堆栈中。 相反,它将回调函数推送到一个称为任务队列
的东西。
这是事件循环开始工作的地方。 事件循环查看堆栈和任务队列。 如果堆栈为空,则会占用队列中的第一个内容并将其推送到堆栈中。
bar
被调用,Second
被打印,它从栈中弹出。
31. 单击按钮时 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
停止冒泡
32. 单击下面的 html 片段打印的内容是什么?
<div onclick="console.log('div')">
<p onclick="console.log('p')">
Click here!
</div>
A:
p
div
B:
div
p
C:
p
D:
div
答案: A
如果我们单击p
,我们会看到两个日志:p
和div
。在事件传播期间,有三个阶段:捕获,目标和冒泡。 默认情况下,事件处理程序在冒泡阶段执行(除非您将useCapture
设置为true
)。 它从最深的嵌套元素向外延伸。
评论