1. 输出是什么?
function sayHi() {
console.log(name)
console.log(age)
var name = 'Lydia'
let age = 21
}
sayHi()
- A:
Lydia和undefined - B:
Lydia和ReferenceError - C:
ReferenceError和21 - D:
undefined和ReferenceError
我的:D(ok)
2. 输出是什么?
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
- A:
0 1 2和0 1 2 - B:
0 1 2和3 3 3 - C:
3 3 3和0 1 2
我的:C(ok)
3. 输出是什么?
const shape = {
radius: 10,
diameter() {
return this.radius * 2
},
perimeter: () => 2 * Math.PI * this.radius
}
shape.diameter()
shape.perimeter()
- A:
20and62.83185307179586 - B:
20andNaN - C:
20and63 - D:
NaNand63
我的:A(error) 正确:B
注意 `diameter` 的值是一个常规函数,但是 `perimeter` 的值是一个箭头函数。
对于箭头函数,`this` 关键字指向的是它当前周围作用域(简单来说是包含箭头函数的常规函数,如果没有常规函数的话就是全局对象),这个行为和常规函数不同。这意味着当我们调用 `perimeter` 时,`this` 不是指向 `shape` 对象,而是它的周围作用域(在例子中是 `window`)。
在 `window` 中没有 `radius` 这个属性,因此返回 `undefined`。
4. 输出是什么?
+true;
!"Lydia";
- A:
1andfalse - B:
falseandNaN - C:
falseandfalse
我的:A(ok?)
一元操作符加号尝试将 bool 转为 number。`true` 转换为 number 的话为 `1`,`false` 为 `0`。
字符串 `'Lydia'` 是一个真值,真值取反那么就返回 `false`。
5. 哪一个是无效的?
const bird = {
size: 'small'
}
const mouse = {
name: 'Mickey',
small: true
}
- A:
mouse.bird.size - B:
mouse[bird.size] - C:
mouse[bird["size"]] - D: All of them are valid
我的:D(error) 正确:A
6. 输出是什么?
let c = { greeting: 'Hey!' }
let d
d = c
c.greeting = 'Hello'
console.log(d.greeting)
- A:
Hello - B:
undefined - C:
ReferenceError - D:
TypeError
我的:A(ok)
在 JavaScript 中,当设置两个对象彼此相等时,它们会通过*引用*进行交互。
首先,变量 `c` 的值是一个对象。接下来,我们给 `d` 分配了一个和 `c` 对象相同的引用。
<img src="https://i.imgur.com/ko5k0fs.png" width="200">
因此当我们改变其中一个对象时,其实是改变了所有的对象。
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:
truefalsetrue - B:
falsefalsetrue - C:
truefalsefalse - D:
falsetruetrue
我的:C(ok)
8. 输出是什么?
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}
constructor({ newColor = 'green' } = {}) {
this.newColor = newColor
}
}
const freddie = new Chameleon({ newColor: 'purple' })
freddie.colorChange('orange')
- A:
orange - B:
purple - C:
green - D:
TypeError
我的:A(error) 正确:D
`colorChange` 是一个静态方法。静态方法被设计为只能被创建它们的构造器使用(也就是 `Chameleon`),并且不能传递给实例。因为 `freddie` 是一个实例,静态方法不能被实例使用,因此抛出了 `TypeError` 错误。
9. 输出是什么?
let greeting
greetign = {} // Typo!
console.log(greetign)
- A:
{} - B:
ReferenceError: greetign is not defined - C:
undefined
我的:A(ok)
代码打印出了一个对象,这是因为我们在全局对象上创建了一个空对象!当我们将 `greeting` 写错成 `greetign` 时,JS 解释器实际在上浏览器中将它视为 `global.greetign = {}` (或者 `window.greetign = {}`)。
为了避免这个为题,我们可以使用 `"use strict"。这能确保当你声明变量时必须赋值。
10. 当我们这么做时,会发生什么?
function bark() {
console.log('Woof!')
}
bark.animal = 'dog'
- A: 正常运行!
- B:
SyntaxError. 你不能通过这种方式给函数增加属性。 - C:
undefined - D:
ReferenceError
我的:A(ok)
11. 输出是什么?
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const member = new Person("Lydia", "Hallie");
Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}
console.log(member.getFullName());
- A:
TypeError - B:
SyntaxError - C:
Lydia Hallie - D:
undefinedundefined
我的:A(ok?)
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(ok?)
13. 事件传播的三个阶段是什么?
- A: Target > Capturing > Bubbling
- B: Bubbling > Target > Capturing
- C: Target > Bubbling > Capturing
- D: Capturing > Target > Bubbling
我的:C(error) 正确:D
14. 所有对象都有原型。
- A: true
- B: false
我的:?
15. 输出是什么?
function sum(a, b) {
return a + b
}
sum(1, '2')
- A:
NaN - B:
TypeError - C:
"12" - D:
3
我的:C(ok)
16. 输出是什么?
let number = 0
console.log(number++)
console.log(++number)
console.log(number)
- A:
112 - B:
122 - C:
022 - D:
012
我的:C(ok)
17. 输出是什么?
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
18. 输出是什么?
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
我的:B(error) 正确:C
19. 输出是什么?
function getAge(...args) {
console.log(typeof args)
}
getAge(21)
- A:
"number" - B:
"array" - C:
"object" - D:
"NaN"
我的:B(error) 正确:C
20. 输出是什么?
function getAge() {
'use strict'
age = 21
console.log(age)
}
getAge()
- A:
21 - B:
undefined - C:
ReferenceError - D:
TypeError
我的:C(ok)
21. 输出是什么?
const sum = eval('10*10+5')
- A:
105 - B:
"105" - C:
TypeError - D:
"10*10+5"
我的:A(ok)
22. cool_secret 可访问多长时间?
sessionStorage.setItem('cool_secret', 123)
- A: 永远,数据不会丢失。
- B: 当用户关掉标签页时。
- C: 当用户关掉整个浏览器,而不只是关掉标签页。
- D: 当用户关闭电脑时。
我的:B(ok)
23. 输出是什么?
var num = 8
var num = 10
console.log(num)
- A:
8 - B:
10 - C:
SyntaxError - D:
ReferenceError
我的:B(ok)
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:
falsetruefalsetrue - B:
falsetruetruetrue - C:
truetruefalsetrue - D:
truetruetruetrue
我的:B(error) 正确:C
所有对象的键(不包括 Symbol)在底层都是字符串,即使你自己没有将其作为字符串输入。这就是为什么 `obj.hasOwnProperty('1')` 也返回 `true`。
对于集合,它不是这样工作的。在我们的集合中没有 `'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(ok)
26. JavaScript 全局执行上下文为你做了两件事:全局对象和 this 关键字。
- A: true
- B: false
- C: it depends
我的:? 正确:A
基本执行上下文是全局执行上下文:它是代码中随处可访问的内容。
27. 输出是什么?
for (let i = 1; i < 5; i++) {
if (i === 3) continue
console.log(i)
}
- A:
12 - B:
123 - C:
124 - D:
134
我的:? 正确: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(ok)
`String` 是内置的构造函数,我们可以向它添加属性。我只是在它的原型中添加了一个方法。基本类型字符串被自动转换为字符串对象,由字符串原型函数生成。因此,所有 string(string 对象)都可以访问该方法!
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
我的:D(error) 正确:B
对象的键被自动转换为字符串。我们试图将一个对象 `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:
FirstSecondThird - B:
FirstThirdSecond - C:
SecondFirstThird - D:
SecondThirdFirst
我的:B(ok)
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: Outer
div - B: Inner
div - C:
button - D: 一个包含所有嵌套元素的数组。
我的:C(ok)
导致事件的最深嵌套的元素是事件的 target。你可以通过 `event.stopPropagation` 来停止冒泡。
32. 当您单击该段落时,日志输出是什么?
<div onclick="console.log('div')">
<p onclick="console.log('p')">
Click here!
</p>
</div>
- A:
pdiv - B:
divp - C:
p - D:
div
我的:A(ok)(gosearch)
如果我们点击 `p`,我们会看到两个日志:`p` 和 `div`。在事件传播期间,有三个阶段:捕获、目标和冒泡。默认情况下,事件处理程序在冒泡阶段执行(除非将 `useCapture` 设置为 `true`)。它从嵌套最深的元素向外传播。
33. 输出是什么?
const person = { name: 'Lydia' }
function sayHi(age) {
console.log(`${this.name} is ${age}`)
}
sayHi.call(person, 21)
sayHi.bind(person, 21)
- A:
undefined is 21Lydia is 21 - B:
functionfunction - C:
Lydia is 21Lydia is 21 - D:
Lydia is 21function
我的:D(ok)
使用这两种方法,我们都可以传递我们希望 `this` 关键字引用的对象。但是,`.call` 是**立即执行**的。
`.bind` 返回函数的**副本**,但带有绑定上下文!它不是立即执行的。
34. 输出是什么?
function sayHi() {
return (() => 0)()
}
typeof sayHi()
- A:
"object" - B:
"number" - C:
"function" - D:
"undefined"
我的:? 正确:B
`sayHi` 方法返回的是立即执行函数(IIFE)的返回值.此立即执行函数的返回值是 `0`, 类型是 `number`
参考:只有7种内置类型:`null`,`undefined`,`boolean`,`number`,`string`,`object` 和 `symbol`。 ``function`` 不是一种类型,函数是对象,它的类型是``object``。
35. 下面哪些值是 falsy?
0
new Number(0)
('')
(' ')
new Boolean(false)
undefined
- A:
0,'',undefined - B:
0,new Number(0),'',new Boolean(false),undefined - C:
0,'',new Boolean(false),undefined - D: All of them are falsy
我的:B(error) 正确:A (gosearch)
只有 6 种 [falsy](https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy) 值:
- `undefined`
- `null`
- `NaN`
- `0`
- `''` (empty string)
- `false`
`Function` 构造函数, 比如 `new Number` 和 `new Boolean`,是 [truthy](https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy)。
36. 输出是什么?
console.log(typeof typeof 1)
- A:
"number" - B:
"string" - C:
"object" - D:
"undefined"
我的:B(ok)
`typeof 1` 返回 `"number"`。
`typeof "number"` 返回 `"string"`。
37. 输出是什么?
const numbers = [1, 2, 3]
numbers[10] = 11
console.log(numbers)
- A:
[1, 2, 3, 7 x null, 11] - B:
[1, 2, 3, 11] - C:
[1, 2, 3, 7 x empty, 11] - D:
SyntaxError
我的:D(error) 正确:C
当你为数组设置超过数组长度的值的时候, JavaScript 会创建名为 "empty slots" 的东西。它们的值实际上是 `undefined`。你会看到以下场景:
`[1, 2, 3, 7 x empty, 11]`
这取决于你的运行环境(每个浏览器,以及 node 环境,都有可能不同)
38. 输出是什么?
(() => {
let x, y
try {
throw new Error()
} catch (x) {
(x = 1), (y = 2)
console.log(x)
}
console.log(x)
console.log(y)
})()
- A:
1undefined2 - B:
undefinedundefinedundefined - C:
112 - D:
1undefinedundefined
我的:? 正确:A
`catch` 代码块接收参数 `x`。当我们传递参数时,这与之前定义的变量 `x` 不同 。这个 `x` 是属于 `catch` 块级作用域的。
然后,我们将块级作用域中的变量赋值为 `1`,同时也设置了变量 `y` 的值。现在,我们打印块级作用域中的变量 `x`,值为 `1`。
`catch` 块之外的变量 `x` 的值仍为 `undefined`, `y` 的值为 `2`。当我们在 `catch` 块之外执行 `console.log(x)` 时,返回 `undefined`,`y` 返回 `2`。
39. JavaScript 中的一切都是?
- A: 基本类型与对象
- B: 函数与对象
- C: 只有对象
- D: 数字与对象
我的:? 正确:A
JavaScript 只有基本类型和对象。
基本类型包括 `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, `symbol`。
40. 输出是什么?
[[0, 1], [2, 3]].reduce(
(acc, cur) => {
return acc.concat(cur)
},
[1, 2]
)
- A:
[0, 1, 2, 3, 1, 2] - B:
[6, 1, 2] - C:
[1, 2, 0, 1, 2, 3] - D:
[1, 2, 6]
我的:? 正确:C (gosearch)
`[1, 2]`是初始值。初始值将会作为首次调用时第一个参数 `acc` 的值。在第一次执行时, `acc` 的值是 `[1, 2]`, `cur` 的值是 `[0, 1]`。合并它们,结果为 `[1, 2, 0, 1]`。
第二次执行, `acc` 的值是 `[1, 2, 0, 1]`, `cur` 的值是 `[2, 3]`。合并它们,最终结果为 `[1, 2, 0, 1, 2, 3]`
41. 输出是什么?
!!null
!!''
!!1
- A:
falsetruefalse - B:
falsefalsetrue - C:
falsetruetrue - D:
truetruefalse
我的:D(ok)(gosearch)
`null` 是 [falsy](https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy)。 `!null` 的值是 `true`。 `!true` 的值是 `false`。
`""` 是 [falsy](https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy)。 `!""` 的值是 `true`。 `!true` 的值是 `false`。
`1` 是 [truthy](https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy)。 `!1` 的值是 `false`。 `!false` 的值是 `true`。
42. setInterval 方法的返回值是什么?
setInterval(() => console.log('Hi'), 1000)
- A: 一个唯一的id
- B: 该方法指定的毫秒数
- C: 传递的函数
- D:
undefined
我的:A(ok)
43. 输出是什么?
[...'Lydia']
- A:
["L", "y", "d", "i", "a"] - B:
["Lydia"] - C:
[[], "Lydia"] - D:
[["L", "y", "d", "i", "a"]]
我的:A(?) 正确:A
string 类型是可迭代的。扩展运算符将迭代的每个字符映射成一个元素。
44. 输出是什么?
function* generator(i) {
yield i;
yield i * 2;
}
const gen = generator(10);
console.log(gen.next().value);
console.log(gen.next().value);
- A:
[0, 10], [10, 20] - B:
20, 20 - C:
10, 20 - D:
0, 10 and 10, 20
我的:? 正确:C (gosearch)
一般的函数在执行之后是不能中途停下的。但是,生成器函数却可以中途“停下”,之后可以再从停下的地方继续。当生成器遇到`yield`关键字的时候,会生成`yield`后面的值。注意,生成器在这种情况下不 _返回_ (_return_ )值,而是 _生成_ (_yield_)值。
首先,我们用`10`作为参数`i`来初始化生成器函数。然后使用`next()`方法一步步执行生成器。第一次执行生成器的时候,`i`的值为`10`,遇到第一个`yield`关键字,它要生成`i`的值。此时,生成器“暂停”,生成了`10`。
然后,我们再执行`next()`方法。生成器会从刚才暂停的地方继续,这个时候`i`还是`10`。于是我们走到了第二个`yield`关键字处,这时候需要生成的值是`i*2`,`i`为`10`,那么此时生成的值便是`20`。所以这道题的最终结果是`10,20`。
45. 返回值是什么?
const firstPromise = new Promise((res, rej) => {
setTimeout(res, 500, "one");
});
const secondPromise = new Promise((res, rej) => {
setTimeout(res, 100, "two");
});
Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
- A:
"one" - B:
"two" - C:
"two" "one" - D:
"one" "two"
我的:? 正确:B
当我们向`Promise.race`方法中传入多个`Promise`时,会进行 _优先_ 解析。在这个例子中,我们用`setTimeout`给`firstPromise`和`secondPromise`分别设定了500ms和100ms的定时器。这意味着`secondPromise`会首先解析出字符串`two`。那么此时`res`参数即为`two`,是为输出结果。
46. 输出是什么?
let person = { name: "Lydia" };
const members = [person];
person = null;
console.log(members);
- A:
null - B:
[null] - C:
[{}] - D:
[{ name: "Lydia" }]
我的:D(?) 正确:D
首先我们声明了一个拥有`name`属性的对象 `person`。
<img src="https://i.imgur.com/TML1MbS.png" width="200">
然后我们又声明了一个变量`members`. 将首个元素赋值为变量`person`。 当设置两个对象彼此相等时,它们会通过 _引用_ 进行交互。但是当你将引用从一个变量分配至另一个变量时,其实只是执行了一个 _复制_ 操作。(注意一点,他们的引用 _并不相同_!)
<img src="https://i.imgur.com/FSG5K3F.png" width="300">
接下来我们让`person`等于`null`。
<img src="https://i.imgur.com/sYjcsMT.png" width="300">
我们没有修改数组第一个元素的值,而只是修改了变量`person`的值,因为元素(复制而来)的引用与`person`不同。`members`的第一个元素仍然保持着对原始对象的引用。当我们输出`members`数组时,第一个元素会将引用的对象打印出来。
47. 输出是什么?
const person = {
name: "Lydia",
age: 21
};
for (const item in person) {
console.log(item);
}
- A:
{ name: "Lydia" }, { age: 21 } - B:
"name", "age" - C:
"Lydia", 21 - D:
["name", "Lydia"], ["age", 21]
我的:? 正确:B
在`for-in`循环中,我们可以通过对象的key来进行迭代,也就是这里的`name`和`age`。在底层,对象的key都是字符串(如果他们不是Symbol的话)。在每次循环中,我们将`item`设定为当前遍历到的key.所以一开始,`item`是`name`,之后 `item`输出的则是`age`。
48. 输出是什么?
console.log(3 + 4 + "5");
- A:
"345" - B:
"75" - C:
12 - D:
"12"
我的:A(error) 正确:B
当所有运算符的 _优先级_ 相同时,计算表达式需要确定运算符的结合顺序,即从右到左还是从左往右。在这个例子中,我们只有一类运算符`+`,对于加法来说,结合顺序就是从左到右。
`3 + 4`首先计算,得到数字`7`.
由于类型的强制转换,`7 + '5'`的结果是`"75"`. JavaScript将`7`转换成了字符串,可以参考问题15.我们可以用`+`号把两个字符串连接起来。 `"7" + "5"` 就得到了`"75"`.
49. num的值是什么?
const num = parseInt("7*6", 10);
- A:
42 - B:
"42" - C:
7 - D:
NaN
我的:A(error) 正确:C
只返回了字符串中第一个字母. 设定了 _进制_ 后 (也就是第二个参数,指定需要解析的数字是什么进制: 十进制、十六机制、八进制、二进制等等……),`parseInt` 检查字符串中的字符是否合法. 一旦遇到一个在指定进制中不合法的字符后,立即停止解析并且忽略后面所有的字符。
`*`就是不合法的数字字符。所以只解析到`"7"`,并将其解析为十进制的`7`. `num`的值即为`7`.
50. 输出是什么?
[1, 2, 3].map(num => {
if (typeof num === "number") return;
return num * 2;
});
- A:
[] - B:
[null, null, null] - C:
[undefined, undefined, undefined] - D:
[ 3 x empty ]
我的:C(ok)
51. 输出的是什么?
function getInfo(member, year) {
member.name = "Lydia";
year = "1998";
}
const person = { name: "Sarah" };
const birthYear = "1997";
getInfo(person, birthYear);
console.log(person, birthYear);
- A:
{ name: "Lydia" }, "1997" - B:
{ name: "Sarah" }, "1998" - C:
{ name: "Lydia" }, "1998" - D:
{ name: "Sarah" }, "1997"
我的:B(error) 正确:A
普通参数都是 _值_ 传递的,而对象则不同,是 _引用_ 传递。所以说,`birthYear`是值传递,因为他是个字符串而不是对象。当我们对参数进行值传递时,会创建一份该值的 _复制_ 。(可以参考问题46)
变量`birthYear`有一个对`"1997"`的引用,而传入的参数也有一个对`"1997"`的引用,但二者的引用并不相同。当我们通过给 `year`赋值`"1998"`来更新`year`的值的时候我们只是更新了`year`(的引用)。此时`birthYear`仍然是`"1997"`.
而`person`是个对象。参数`member`引用与之 _相同的_ 对象。当我们修改`member`所引用对象的属性时,`person`的相应属性也被修改了,因为他们引用了相同的对象. `person`的 `name`属性也变成了 `"Lydia"`.
52. 输出是什么?
function greeting() {
throw "Hello world!";
}
function sayHi() {
try {
const data = greeting();
console.log("It worked!", data);
} catch (e) {
console.log("Oh no an error!", e);
}
}
sayHi();
- A:
"It worked! Hello world!" - B:
"Oh no an error: undefined - C:
SyntaxError: can only throw Error objects - D:
"Oh no an error: Hello world!
我的:D(ok)
通过`throw`语句,我么可以创建自定义错误。 而通过它,我们可以抛出异常。异常可以是一个<b>字符串</b>, 一个 <b>数字</b>, 一个 <b>布尔类型</b> 或者是一个 <b>对象</b>。在本例中,我们的异常是字符串`'Hello world'`.
通过 `catch`语句,我们可以设定当`try`语句块中抛出异常后应该做什么处理。在本例中抛出的异常是字符串`'Hello world'`. `e`就是这个字符串,因此被输出。最终结果就是`'Oh an error: Hello world'`.
53. 输出是什么?
function Car() {
this.make = "Lamborghini";
return { make: "Maserati" };
}
const myCar = new Car();
console.log(myCar.make);
- A:
"Lamborghini" - B:
"Maserati" - C:
ReferenceError - D:
TypeError
我的:? 正确:B
返回属性的时候,属性的值等于 _返回的_ 值,而不是构造函数中设定的值。我们返回了字符串 `"Maserati"`,所以 `myCar.make`等于`"Maserati"`.
54. 输出是什么?
(() => {
let x = (y = 10);
})();
console.log(typeof x);
console.log(typeof y);
- A:
"undefined", "number" - B:
"number", "number" - C:
"object", "number" - D:
"number", "undefined"
我的:A(ok)
`let x = y = 10;` 是下面这个表达式的缩写:
```javascript
y = 10;
let x = y;
```
我们设定`y`等于`10`时,我们实际上增加了一个属性`y`给全局对象(浏览器里的`window`, Nodejs里的`global`)。在浏览器中, `window.y`等于`10`.
然后我们声明了变量`x`等于`y`,也是`10`.但变量是使用 `let`声明的,它只作用于 _块级作用域_, 仅在声明它的块中有效;就是案例中的立即调用表达式(IIFE)。使用`typeof`操作符时, 操作值 `x`没有被定义:因为我们在`x`声明块的外部,无法调用它。这就意味着`x`未定义。未分配或是未声明的变量类型为`"undefined"`. `console.log(typeof x)`返回`"undefined"`.
而我们创建了全局变量`y`,并且设定`y`等于`10`.这个值在我们的代码各处都访问的到。 `y`已经被定义了,而且有一个`"number"`类型的值。 `console.log(typeof y)`返回`"number"`.
55. 输出是什么?
class Dog {
constructor(name) {
this.name = name;
}
}
Dog.prototype.bark = function() {
console.log(`Woof I am ${this.name}`);
};
const pet = new Dog("Mara");
pet.bark();
delete Dog.prototype.bark;
pet.bark();
- A:
"Woof I am Mara",TypeError - B:
"Woof I am Mara","Woof I am Mara" - C:
"Woof I am Mara",undefined - D:
TypeError,TypeError
我的:A(ok)
我们可以用`delete`关键字删除对象的属性,对原型也是适用的。删除了原型的属性后,该属性在原型链上就不可用了。在本例中,函数`bark`在执行了`delete Dog.prototype.bark`后不可用, 然而后面的代码还在调用它。
当我们尝试调用一个不存在的函数时`TypeError`异常会被抛出。在本例中就是 `TypeError: pet.bark is not a function`,因为`pet.bark`是`undefined`.
56. 输出是什么?
const set = new Set([1, 1, 2, 3, 4]);
console.log(set);
- A:
[1, 1, 2, 3, 4] - B:
[1, 2, 3, 4] - C:
{1, 1, 2, 3, 4} - D:
{1, 2, 3, 4}
我的:B(error) 正确:D
`Set`对象是独一无二的值的集合:也就是说同一个值在其中仅出现一次。
我们传入了数组`[1, 1, 2, 3, 4]`,他有一个重复值`1`.以为一个集合里不能有两个重复的值,其中一个就被移除了。所以结果是 `{1, 2, 3, 4}`.
57. 输出是什么?
// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter";
myCounter += 1;
console.log(myCounter);
- A:
10 - B:
11 - C:
Error - D:
NaN
我的:A(error) 正确:C
引入的模块是 _只读_ 的: 你不能修改引入的模块。只有导出他们的模块才能修改其值。
当我们给`myCounter`增加一个值的时候会抛出一个异常: `myCounter`是只读的,不能被修改。
58. 输出是什么?
const name = "Lydia";
age = 21;
console.log(delete name);
console.log(delete age);
- A:
false,true - B:
"Lydia",21 - C:
true,true - D:
undefined,undefined
我的:? 正确:A
`delete`操作符返回一个布尔值: `true`指删除成功,否则返回`false`. 但是通过 `var`, `const` 或 `let` 关键字声明的变量无法用 `delete` 操作符来删除。
`name`变量由`const`关键字声明,所以删除不成功:返回 `false`. 而我们设定`age`等于`21`时,我们实际上添加了一个名为`age`的属性给全局对象。对象中的属性是可以删除的,全局对象也是如此,所以`delete age`返回`true`.
59. 输出是什么?
const numbers = [1, 2, 3, 4, 5];
const [y] = numbers;
console.log(y);
- A:
[[1, 2, 3, 4, 5]] - B:
[1, 2, 3, 4, 5] - C:
1 - D:
[1]
我的:? 正确:C
我们可以通过解构赋值来解析来自对象的数组或属性的值,比如说:
```javascript
[a, b] = [1, 2];
```
<img src="https://i.imgur.com/ADFpVop.png" width="200">
`a`的值现在是`1`,`b`的值现在是`2`.而在题目中,我们是这么做的:
```javascript
[y] = [1, 2, 3, 4, 5];
```
<img src="https://i.imgur.com/NzGkMNk.png" width="200">
也就是说,`y`等于数组的第一个值就是数字`1`.我们输出`y`, 返回`1`.
60. 输出是什么?
const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user };
console.log(admin);
- A:
{ admin: true, user: { name: "Lydia", age: 21 } } - B:
{ admin: true, name: "Lydia", age: 21 } - C:
{ admin: true, user: ["Lydia", 21] } - D:
{ admin: true }
我的:B(ok)
61. 输出是什么?
const person = { name: "Lydia" };
Object.defineProperty(person, "age", { value: 21 });
console.log(person);
console.log(Object.keys(person));
- A:
{ name: "Lydia", age: 21 },["name", "age"] - B:
{ name: "Lydia", age: 21 },["name"] - C:
{ name: "Lydia"},["name", "age"] - D:
{ name: "Lydia"},["age"]
我的:A(error) 正确:B
通过`defineProperty`方法,我们可以给对象添加一个新属性,或者修改已经存在的属性。而我们使用`defineProperty`方法给对象添加了一个属性之后,属性默认为 _不可枚举(not enumerable)_. `Object.keys`方法仅返回对象中 _可枚举(enumerable)_ 的属性,因此只剩下了`"name"`.
用`defineProperty`方法添加的属性默认不可变。你可以通过`writable`, `configurable` 和 `enumerable`属性来改变这一行为。这样的话, 相比于自己添加的属性,`defineProperty`方法添加的属性有了更多的控制权。
62. 输出是什么?
const settings = {
username: "lydiahallie",
level: 19,
health: 90
};
const data = JSON.stringify(settings, ["level", "health"]);
console.log(data);
- A:
"{"level":19, "health":90}" - B:
"{"username": "lydiahallie"}" - C:
"["level", "health"]" - D:
"{"username": "lydiahallie", "level":19, "health":90}"
我的:A(ok)(gosearch)
`JSON.stringify`的第二个参数是 _替代者(replacer)_. 替代者(replacer)可以是个函数或数组,用以控制哪些值如何被转换为字符串。
如果替代者(replacer)是个 _数组_ ,那么就只有包含在数组中的属性将会被转化为字符串。在本例中,只有名为`"level"` 和 `"health"` 的属性被包括进来, `"username"`则被排除在外。 `data` 就等于 `"{"level":19, "health":90}"`.
而如果替代者(replacer)是个 _函数_,这个函数将被对象的每个属性都调用一遍。
函数返回的值会成为这个属性的值,最终体现在转化后的JSON字符串中(译者注:Chrome下,经过实验,如果所有属性均返回同一个值的时候有异常,会直接将返回值作为结果输出而不会输出JSON字符串),而如果返回值为`undefined`,则该属性会被排除在外。
63. 输出是什么?
let num = 10;
const increaseNumber = () => num++;
const increasePassedNumber = number => number++;
const num1 = increaseNumber();
const num2 = increasePassedNumber(num1);
console.log(num1);
console.log(num2);
- A:
10,10 - B:
10,11 - C:
11,11 - D:
11,12
我的:D(error) 正确:A
一元操作符 `++` _先返回_ 操作值, _再累加_ 操作值。`num1`的值是`10`, 因为`increaseNumber`函数首先返回`num`的值,也就是`10`,随后再进行 `num`的累加。
`num2`是`10`因为我们将 `num1`传入`increasePassedNumber`. `number`等于`10`(`num1`的值。同样道理,`++` _先返回_ 操作值, _再累加_ 操作值。) `number`是`10`,所以`num2`也是`10`.
64. 输出什么?
const value = { number: 10 };
const multiply = (x = { ...value }) => {
console.log(x.number *= 2);
};
multiply();
multiply();
multiply(value);
multiply(value);
- A:
20,40,80,160 - B:
20,40,20,40 - C:
20,20,20,40 - D:
NaN,NaN,20,40
我的:D(error) 正确:C
在ES6中,我们可以使用默认值初始化参数。如果没有给函数传参,或者传的参值为 `"undefined"` ,那么参数的值将是默认值。上述例子中,我们将 `value` 对象进行了解构并传到一个新对象中,因此 `x` 的默认值为 `{number:10}` 。
默认参数在调用时才会进行计算,每次调用函数时,都会创建一个新的对象。我们前两次调用 `multiply` 函数且不传递值,那么每一次 `x` 的默认值都为 `{number:10}` ,因此打印出该数字的乘积值为`20`。
第三次调用 `multiply` 时,我们传递了一个参数,即对象`value`。 `*=`运算符实际上是`x.number = x.number * 2`的简写,我们修改了`x.number`的值,并打印出值`20`。
第四次,我们再次传递`value`对象。 `x.number`之前被修改为`20`,所以`x.number * = 2`打印为`40`。
65. 输出什么?
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));
- A:
12and33and64 - B:
12and23and34 - C:
1undefinedand2undefinedand3undefinedand4undefined - D:
12andundefined3andundefined4
我的:? 正确:D (gosearch)
`reducer` 函数接收4个参数:
1. Accumulator (acc) (累计器)
2. Current Value (cur) (当前值)
3. Current Index (idx) (当前索引)
4. Source Array (src) (源数组)
`reducer` 函数的返回值将会分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
`reducer` 函数还有一个可选参数`initialValue`, 该参数将作为第一次调用回调函数时的第一个参数的值。如果没有提供`initialValue`,则将使用数组中的第一个元素。
在上述例子,`reduce`方法接收的第一个参数(Accumulator)是`x`, 第二个参数(Current Value)是`y`。
在第一次调用时,累加器`x`为`1`,当前值`“y”`为`2`,打印出累加器和当前值:`1`和`2`。
例子中我们的回调函数没有返回任何值,只是打印累加器的值和当前值。如果函数没有返回值,则默认返回`undefined`。 在下一次调用时,累加器为`undefined`,当前值为“3”, 因此`undefined`和`3`被打印出。
在第四次调用时,回调函数依然没有返回值。 累加器再次为 `undefined` ,当前值为“4”。 `undefined`和`4`被打印出。
66. 使用哪个构造函数可以成功继承Dog类?
class Dog {
constructor(name) {
this.name = name;
}
};
class Labrador extends Dog {
// 1
constructor(name, size) {
this.size = size;
}
// 2
constructor(name, size) {
super(name);
this.size = size;
}
// 3
constructor(size) {
super(name);
this.size = size;
}
// 4
constructor(name, size) {
this.name = name;
this.size = size;
}
};
- A: 1
- B: 2
- C: 3
- D: 4
我的:B(ok)
在子类中,在调用`super`之前不能访问到`this`关键字。 如果这样做,它将抛出一个`ReferenceError`:1和4将引发一个引用错误。
使用`super`关键字,需要用给定的参数来调用父类的构造函数。 父类的构造函数接收`name`参数,因此我们需要将`name`传递给`super`。
`Labrador`类接收两个参数,`name`参数是由于它继承了`Dog`,`size`作为`Labrador`类的额外属性,它们都需要传递给`Labrador`的构造函数,因此使用构造函数2正确完成。
67. 输出什么?
// index.js
console.log('running index.js');
import { sum } from './sum.js';
console.log(sum(1, 2));
// sum.js
console.log('running sum.js');
export const sum = (a, b) => a + b;
- A:
running index.js,running sum.js,3 - B:
running sum.js,running index.js,3 - C:
running sum.js,3,running index.js - D:
running index.js,undefined,running sum.js
我的:A(error) 正确:B
`import`命令是编译阶段执行的,在代码运行之前。因此这意味着被导入的模块会先运行,而导入模块的文件会后执行。
这是CommonJS中`require()`和`import`之间的区别。使用`require()`,您可以在运行代码时根据需要加载依赖项。 如果我们使用`require`而不是`import`,`running index.js`,`running sum.js`,`3`会被依次打印。
68. 输出什么?
console.log(Number(2) === Number(2))
console.log(Boolean(false) === Boolean(false))
console.log(Symbol('foo') === Symbol('foo'))
- A:
true,true,false - B:
false,true,false - C:
true,false,true - D:
true,true,true
我的:? 正确:A (gosearch)
每个`Symbol`都是完全唯一的。传递给`Symbol`的参数只是给`Symbol`的一个描述。 `Symbol`的值不依赖于传递的参数。 当我们测试相等时,我们创建了两个全新的符号:第一个`Symbol('foo')`,第二个`Symbol('foo')`, 这两个值是唯一的,彼此不相等,因此返回`false`。
69. 输出什么?
const name = "Lydia Hallie"
console.log(name.padStart(13))
console.log(name.padStart(2))
- A:
"Lydia Hallie","Lydia Hallie" - B:
" Lydia Hallie"," Lydia Hallie"("[13x whitespace]Lydia Hallie","[2x whitespace]Lydia Hallie") - C:
" Lydia Hallie","Lydia Hallie"("[1x whitespace]Lydia Hallie","Lydia Hallie") - D:
"Lydia Hallie","Lyd"
我的:? 正确:C (gosearch)
使用`padStart`方法,我们可以在字符串的开头添加填充。传递给此方法的参数是字符串的总长度(包含填充)。字符串`Lydia Hallie`的长度为`12`, 因此`name.padStart(13)`在字符串的开头只会插入1(`13 - 12 = 1`)个空格。
如果传递给`padStart`方法的参数小于字符串的长度,则不会添加填充。
70. 输出什么?
console.log("🥑" + "💻");
- A:
"🥑💻" - B:
257548 - C: A string containing their code points
- D: Error
我的:A(ok)
71. 如何能打印出console.log语句后注释掉的值?
function* startGame() {
const answer = yield "Do you love JavaScript?";
if (answer !== "Yes") {
return "Oh wow... Guess we're gone here";
}
return "JavaScript loves you back ❤️";
}
const game = startGame();
console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️
- A:
game.next("Yes").valueandgame.next().value - B:
game.next.value("Yes")andgame.next.value() - C:
game.next().valueandgame.next("Yes").value - D:
game.next.value()andgame.next.value("Yes")
我的:? 正确:C (gosearch)
`generator`函数在遇到`yield`关键字时会“暂停”其执行。 首先,我们需要让函数产生字符串`Do you love JavaScript?`,这可以通过调用`game.next().value`来完成。上述函数的第一行就有一个`yield`关键字,那么运行立即停止了,`yield`表达式本身没有返回值,或者说总是返回`undefined`, 这意味着此时变量 `answer` 为`undefined`
`next`方法可以带一个参数,该参数会被当作上一个 `yield` 表达式的返回值。当我们调用`game.next("Yes").value`时,先前的 `yield` 的返回值将被替换为传递给`next()`函数的参数`"Yes"`。此时变量 `answer` 被赋值为 `"Yes"`,`if`语句返回`false`,所以`JavaScript loves you back ❤️`被打印。
72. 输出什么?
console.log(String.raw`Hello\nworld`);
- A:
Hello world! - B:
Helloworld - C:
Hello\nworld - D:
Hello\nworld
我的:B(error) 正确:C (gosearch)
`String.raw`函数是用来获取一个模板字符串的原始字符串的,它返回一个字符串,其中忽略了转义符(`\n`,`\v`,`\t`等)。但反斜杠可能造成问题,因为你可能会遇到下面这种类似情况:
```javascript
const path = `C:\Documents\Projects\table.html`
String.raw`${path}`
```
这将导致:
`"C:DocumentsProjects able.html"`
直接使用`String.raw`
```javascript
String.raw`C:\Documents\Projects\table.html`
```
它会忽略转义字符并打印:`C:\Documents\Projects\table.html`
上述情况,字符串是`Hello\nworld`被打印出。
73. 输出什么?
async function getData() {
return await Promise.resolve("I made it!");
}
const data = getData();
console.log(data);
- A:
"I made it!" - B:
Promise {<resolved>: "I made it!"} - C:
Promise {<pending>} - D:
undefined
我的:? 正确:C
异步函数始终返回一个promise。`await`仍然需要等待promise的解决:当我们调用`getData()`并将其赋值给`data`,此时`data`为`getData`方法返回的一个挂起的promise,该promise并没有解决。
如果我们想要访问已解决的值`"I made it!"`,可以在`data`上使用`.then()`方法:
`data.then(res => console.log(res))`
这样将打印 `"I made it!"`
74. 输出什么?
function addToList(item, list) {
return list.push(item);
}
const result = addToList("apple", ["banana"]);
console.log(result);
- A:
['apple', 'banana'] - B:
2 - C:
true - D:
undefined
我的:B(ok)
`push()`方法返回新数组的长度。一开始,数组包含一个元素(字符串`"banana"`),长度为1。 在数组中添加字符串`"apple"`后,长度变为2,并将从`addToList`函数返回。
`push`方法修改原始数组,如果你想从函数返回数组而不是数组长度,那么应该在push `item`之后返回`list`。
75. 输出什么?
const box = { x: 10, y: 20 };
Object.freeze(box);
const shape = box;
shape.x = 100;
console.log(shape)
- A:
{ x: 100, y: 20 } - B:
{ x: 10, y: 20 } - C:
{ x: 100 } - D:
ReferenceError
我的:C(error) 正确:B
`Object.freeze`使得无法添加、删除或修改对象的属性(除非属性的值是另一个对象)。
当我们创建变量`shape`并将其设置为等于冻结对象`box`时,`shape`指向的也是冻结对象。你可以使用`Object.isFrozen`检查一个对象是否被冻结,上述情况,`Object.isFrozen(shape)`将返回`true`。
由于`shape`被冻结,并且`x`的值不是对象,所以我们不能修改属性`x`。 `x`仍然等于`10`,`{x:10,y:20}`被打印。
注意,上述例子我们对属性`x`进行修改,可能会导致抛出TypeError异常(最常见但不仅限于严格模式下时)。
76. 输出什么?
const { name: myName } = { name: "Lydia" };
console.log(name);
- A:
"Lydia" - B:
"myName" - C:
undefined - D:
ReferenceError
我的:? 正确:D
当我们从右侧的对象解构属性`name`时,我们将其值`Lydia`分配给名为`myName`的变量。
使用`{name:myName}`,我们是在告诉JavaScript我们要创建一个名为`myName`的新变量,并且其值是右侧对象的`name`属性的值。
当我们尝试打印`name`,一个未定义的变量时,就会引发`ReferenceError`。
77. 以下是个纯函数么?
function sum(a, b) {
return a + b;
}
- A: Yes
- B: No
我的:A(ok)
纯函数一种若输入参数相同,则永远会得到相同输出的函数。
`sum`函数总是返回相同的结果。 如果我们传递`1`和`2`,它将总是返回`3`而没有副作用。 如果我们传递`5`和`10`,它将总是返回`15`,依此类推,这是纯函数的定义。
78. 输出什么?
const add = () => {
const cache = {};
return num => {
if (num in cache) {
return `From cache! ${cache[num]}`;
} else {
const result = num + 10;
cache[num] = result;
return `Calculated! ${result}`;
}
};
};
const addFunction = add();
console.log(addFunction(10));
console.log(addFunction(10));
console.log(addFunction(5 * 2));
- A:
Calculated! 20Calculated! 20Calculated! 20 - B:
Calculated! 20From cache! 20Calculated! 20 - C:
Calculated! 20From cache! 20From cache! 20 - D:
Calculated! 20From cache! 20Error
我的:C(ok)
79. 输出什么?
const myLifeSummedUp = ["☕", "💻", "🍷", "🍫"]
for (let item in myLifeSummedUp) {
console.log(item)
}
for (let item of myLifeSummedUp) {
console.log(item)
}
- A:
0123and"☕""💻""🍷""🍫" - B:
"☕""💻""🍷""🍫"and"☕""💻""🍷""🍫" - C:
"☕""💻""🍷""🍫"and0123 - D:
0123and{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}
我的:A(ok)
80. 输出什么?
const list = [1 + 2, 1 * 2, 1 / 2]
console.log(list)
- A:
["1 + 2", "1 * 2", "1 / 2"] - B:
["12", 2, 0.5] - C:
[3, 2, 0.5] - D:
[1, 1, 1]
我的:C(ok)
81. 输出什么?
function sayHi(name) {
return `Hi there, ${name}`
}
console.log(sayHi())
- A:
Hi there, - B:
Hi there, undefined - C:
Hi there, null - D:
ReferenceError
我的:B(ok)
82. 输出什么?
var status = "😎"
setTimeout(() => {
const status = "😍"
const data = {
status: "🥑",
getStatus() {
return this.status
}
}
console.log(data.getStatus())
console.log(data.getStatus.call(this))
}, 0)
- A:
"🥑"and"😍" - B:
"🥑"and"😎" - C:
"😍"and"😎" - D:
"😎"and"😎"
我的:A(error) 正确:B
`this`关键字的指向取决于使用它的位置。 在**函数**中,比如`getStatus`,`this`指向的是调用它的对象,上述例子中`data`对象调用了`getStatus`,因此`this`指向的就是`data`对象。 当我们打印`this.status`时,`data`对象的`status`属性被打印,即`"🥑"`。
使用`call`方法,可以更改`this`指向的对象。`data.getStatus.call(this)`是将`this`的指向由`data`对象更改为全局对象。在全局对象上,有一个名为`status`的变量,其值为`”😎“`。 因此打印`this.status`时,会打印`“😎”`。
83. 输出什么?
const person = {
name: "Lydia",
age: 21
}
let city = person.city
city = "Amsterdam"
console.log(person)
- A:
{ name: "Lydia", age: 21 } - B:
{ name: "Lydia", age: 21, city: "Amsterdam" } - C:
{ name: "Lydia", age: 21, city: undefined } - D:
"Amsterdam"
我的:B(error) 正确:A
我们将变量`city`设置为等于`person`对象上名为`city`的属性的值。 这个对象上没有名为`city`的属性,因此变量`city`的值为`undefined`。
请注意,我们没有引用`person`对象本身,只是将变量`city`设置为等于`person`对象上`city`属性的当前值。
然后,我们将`city`设置为等于字符串`“Amsterdam”`。 这不会更改person对象:没有对该对象的引用。
因此打印`person`对象时,会返回未修改的对象。
84. 输出什么?
function checkAge(age) {
if (age < 18) {
const message = "Sorry, you're too young."
} else {
const message = "Yay! You're old enough!"
}
return message
}
console.log(checkAge(21))
- A:
"Sorry, you're too young." - B:
"Yay! You're old enough!" - C:
ReferenceError - D:
undefined
我的:D(error) 正确:C
`const`和`let`声明的变量是具有**块级作用域**的,块是大括号(`{}`)之间的任何东西, 即上述情况`if / else`语句的花括号。 由于块级作用域,我们无法在声明的块之外引用变量,因此抛出`ReferenceError`。
85. 什么样的信息将被打印?
fetch('https://www.website.com/api/user/1')
.then(res => res.json())
.then(res => console.log(res))
- A:
fetch方法的结果 - B: 第二次调用
fetch方法的结果 - C: 前一个
.then()中回调方法返回的结果 - D: 总是
undefined
我的:? 正确:C
第二个`.then`中`res`的值等于前一个`.then`中的回调函数返回的值。 你可以像这样继续链接`.then`,将值传递给下一个处理程序。
86. 哪个选项是将hasName设置为true的方法,前提是不能将true作为参数传递?
function getName(name) {
const hasName = //
}
- A:
!!name - B:
name - C:
new Boolean(name) - D:
name.length
我的:A(ok)
使用逻辑非运算符`!`,将返回一个布尔值,使用`!! name`,我们可以确定`name`的值是真的还是假的。 如果`name`是真实的,那么`!name`返回`false`。 `!false`返回`true`。
通过将`hasName`设置为`name`,可以将`hasName`设置为等于传递给`getName`函数的值,而不是布尔值`true`。
`new Boolean(true)`返回一个对象包装器,而不是布尔值本身。
`name.length`返回传递的参数的长度,而不是布尔值`true`。
console.log(!true); //false
console.log(!!true); //true
console.log(!!!true);//false
87. 输出什么?
console.log("I want pizza"[0])
- A:
""" - B:
"I" - C:
SyntaxError - D:
undefined
我的:B(ok)
88. 输出什么?
function sum(num1, num2 = num1) {
console.log(num1 + num2)
}
sum(10)
- A:
NaN - B:
20 - C:
ReferenceError - D:
undefined
我的:B(ok)
您可以将默认参数的值设置为函数的另一个参数,只要另一个参数定义在其之前即可。 我们将值`10`传递给`sum`函数。 如果`sum`函数只接收1个参数,则意味着没有传递`num2`的值,这种情况下,`num1`的值等于传递的值`10`。 `num2`的默认值是`num1`的值,即`10`。 ```num1 + num2```返回`20`。
如果您尝试将默认参数的值设置为后面定义的参数,则可能导致参数的值尚未初始化,从而引发错误。比如:
```js
function test(m = n, n = 2) {
console.log(m, n)
}
test() // Uncaught ReferenceError: Cannot access 'n' before initialization
test(3) // 3 2
test(3, 4) // 3 4
89. 输出什么?
// module.js
export default () => "Hello world"
export const name = "Lydia"
// index.js
import * as data from "./module"
console.log(data)
- A:
{ default: function default(), name: "Lydia" } - B:
{ default: function default() } - C:
{ default: "Hello world", name: "Lydia" } - D: Global object of
module.js
我的:A(ok)
使用`import * as name`语法,我们将`module.js`文件中所有`export`导入到`index.js`文件中,并且创建了一个名为`data`的新对象。 在`module.js`文件中,有两个导出:默认导出和命名导出。 默认导出是一个返回字符串“Hello World”的函数,命名导出是一个名为`name`的变量,其值为字符串`“Lydia”`。
`data`对象具有默认导出的`default`属性,其他属性具有指定exports的名称及其对应的值。
90. 输出什么?
class Person {
constructor(name) {
this.name = name
}
}
const member = new Person("John")
console.log(typeof member)
- A:
"class" - B:
"function" - C:
"object" - D:
"string"
我的:C(ok)
类是构造函数的语法糖,如果用构造函数的方式来重写`Person`类则将是:
```javascript
function Person() {
this.name = name
}
```
通过`new`来调用构造函数,将会生成构造函数`Person`的实例,对实例执行`typeof`关键字将返回`"object"`,上述情况打印出`"object"`。
console.log(typeof Person); //function
91. 输出什么?
let newList = [1, 2, 3].push(4) // 4
console.log(newList.push(5))
- A:
[1, 2, 3, 4, 5] - B:
[1, 2, 3, 5] - C:
[1, 2, 3, 4] - D:
Error
我的:A(?) 正确:D
`.push`方法返回数组的长度,而不是数组本身! 通过将`newList`设置为`[1,2,3].push(4)`,实际上`newList`等于数组的新长度:`4`。
然后,尝试在`newList`上使用`.push`方法。 由于`newList`是数值`4`,抛出TypeError。
console.log([].push(2)); //1
console.log([1].push(2)); //2
console.log([1,2].push(2)); //3
console.log([1,2,3].push(2)); //4
92. 输出什么?
function giveLydiaPizza() {
return "Here is pizza!"
}
const giveLydiaChocolate = () => "Here's chocolate... now go hit the gym already."
console.log(giveLydiaPizza.prototype)
console.log(giveLydiaChocolate.prototype)
- A:
{ constructor: ...}{ constructor: ...} - B:
{}{ constructor: ...} - C:
{ constructor: ...}{} - D:
{ constructor: ...}undefined
我的:A(?) 正确:D
常规函数,例如`giveLydiaPizza`函数,有一个`prototype`属性,它是一个带有`constructor`属性的对象(原型对象)。 然而,箭头函数,例如`giveLydiaChocolate`函数,没有这个`prototype`属性。 尝试使用`giveLydiaChocolate.prototype`访问`prototype`属性时会返回`undefined`。
93. 输出什么?
const person = {
name: "Lydia",
age: 21
}
for (const [x, y] of Object.entries(person)) {
console.log(x, y)
}
- A:
nameLydiaandage21 - B:
["name", "Lydia"]and["age", 21] - C:
["name", "age"]andundefined - D:
Error
我的:? 正确:B (gosearch)
`Object.entries()`方法返回一个给定对象自身可枚举属性的键值对数组,上述情况返回一个二维数组,数组每个元素是一个包含键和值的数组:
`[['name','Lydia'],['age',21]]`
使用`for-of`循环,我们可以迭代数组中的每个元素,上述情况是子数组。 我们可以使用`const [x,y]`在`for-of`循环中解构子数组。 `x`等于子数组中的第一个元素,`y`等于子数组中的第二个元素。
第一个子阵列是`[“name”,“Lydia”]`,其中`x`等于`name`,而`y`等于`Lydia`。
第二个子阵列是`[“age”,21]`,其中`x`等于`age`,而`y`等于`21`。
var result = Object.entries(person);
console.log(result); //[['name','Lydia'],['age',21]];
console.log(result[0]); //['name','Lydia']
console.log(result[1]); //['age',21]
94. 输出什么?
function getItems(fruitList, ...args, favoriteFruit) {
return [...fruitList, ...args, favoriteFruit]
}
getItems(["banana", "apple"], "pear", "orange")
- A:
["banana", "apple", "pear", "orange"] - B:
[["banana", "apple"], "pear", "orange"] - C:
["banana", "apple", ["pear"], "orange"] - D:
SyntaxError
我的:? 正确:D
`... args`是剩余参数,剩余参数的值是一个包含所有剩余参数的数组,**并且只能作为最后一个参数**。上述示例中,剩余参数是第二个参数,这是不可能的,并会抛出语法错误。
```javascript
function getItems(fruitList, favoriteFruit, ...args) {
return [...fruitList, ...args, favoriteFruit]
}
getItems(["banana", "apple"], "pear", "orange")
```
上述例子是有效的,将会返回数组:`[ 'banana', 'apple', 'orange', 'pear' ]`
function getItems(fruitList, favoriteFruit, ...args) {
return [...fruitList, ...args, favoriteFruit]
}
getItems(["banana", "apple"], "pear", "orange"); //["banana", "apple", "orange", "pear"]
function getItems(fruitList, favoriteFruit, ...args) {
return [...fruitList, favoriteFruit, ...args]
}
getItems(["banana", "apple"], "pear", "orange"); //["banana", "apple", "pear", "orange"]
95. 输出什么?
function nums(a, b) {
if
(a > b)
console.log('a is bigger')
else
console.log('b is bigger')
return
a + b
}
console.log(nums(4, 2))
console.log(nums(1, 2))
- A:
a is bigger,6andb is bigger,3 - B:
a is bigger,undefinedandb is bigger,undefined - C:
undefinedandundefined - D:
SyntaxError
我的:A(error) 正确:B
function nums(a, b) {
if(a > b){
console.log('a is bigger')
}else {
console.log('b is bigger')
}
return;
a + b
}
console.log(nums(4, 2)); // `a is bigger`, `undefined`
console.log(nums(1, 2)); // `b is bigger`, `undefined`
function nums(a, b) {
if(a > b){
console.log('a is bigger')
}else {
console.log('b is bigger')
}
return a + b;
}
console.log(nums(4, 2)); //`a is bigger`, `6`
console.log(nums(1, 2)); //`b is bigger`, `3`
96. 输出什么?
class Person {
constructor() {
this.name = "Lydia"
}
}
Person = class AnotherPerson {
constructor() {
this.name = "Sarah"
}
}
const member = new Person()
console.log(member.name)
- A:
"Lydia" - B:
"Sarah" - C:
Error: cannot redeclare Person - D:
SyntaxError
我的:B(?) 正确:B
我们可以将类设置为等于其他类/函数构造函数。 在这种情况下,我们将`Person`设置为`AnotherPerson`。 这个构造函数的名字是`Sarah`,所以新的`Person`实例`member`上的name属性是`Sarah`。
97. 输出什么?
const info = {
[Symbol('a')]: 'b'
}
console.log(info)
console.log(Object.keys(info))
- A:
{Symbol('a'): 'b'}and["{Symbol('a')"] - B:
{}and[] - C:
{ a: "b" }and["a"] - D:
{Symbol('a'): 'b'}and[]
我的:? 正确:D (gosearch)
`Symbol`类型是不可枚举的。`Object.keys`方法返回对象上的所有可枚举的键属性。`Symbol`类型是不可见的,并返回一个空数组。 记录整个对象时,所有属性都是可见的,甚至是不可枚举的属性。
这是`Symbol`的众多特性之一:除了表示完全唯一的值(防止对象意外名称冲突,例如当使用2个想要向同一对象添加属性的库时),您还可以`隐藏`这种方式对象的属性(尽管不完全。你仍然可以使用`Object.getOwnPropertySymbols()`方法访问 `Symbol`。
98. 输出什么?
const getList = ([x, ...y]) => [x, y]
const getUser = user => { name: user.name, age: user.age }
const list = [1, 2, 3, 4]
const user = { name: "Lydia", age: 21 }
console.log(getList(list))
console.log(getUser(user))
- A:
[1, [2, 3, 4]]andundefined - B:
[1, [2, 3, 4]]and{ name: "Lydia", age: 21 } - C:
[1, 2, 3, 4]and{ name: "Lydia", age: 21 } - D:
Errorand{ name: "Lydia", age: 21 }
我的:? 正确:A
`getList`函数接收一个数组作为其参数。 在`getList`函数的括号之间,我们立即解构这个数组。 您可以将其视为:
`[x, ...y] = [1, 2, 3, 4]`
使用剩余的参数`... y`,我们将所有剩余参数放在一个数组中。 在这种情况下,其余的参数是`2`,`3`和`4`。 `y`的值是一个数组,包含所有其余参数。 在这种情况下,`x`的值等于`1`,所以当我们打印`[x,y]`时,会打印`[1,[2,3,4]]`。
`getUser`函数接收一个对象。对于箭头函数,如果只返回一个值,我们不必编写花括号。但是,如果您想从一个箭头函数返回一个对象,您必须在圆括号之间编写它,否则不会返回任何值!下面的函数将返回一个对象:
```const getUser = user => ({ name: user.name, age: user.age })```
由于在这种情况下不返回任何值,因此该函数返回`undefined`。
99. 输出什么?
const name = "Lydia"
console.log(name())
- A:
SyntaxError - B:
ReferenceError - C:
TypeError - D:
undefined
我的:? 正确:C
变量`name`保存字符串的值,该字符串不是函数,因此无法调用。
当值不是预期类型时,会抛出`TypeErrors`。 JavaScript期望`name`是一个函数,因为我们试图调用它。 但它是一个字符串,因此抛出`TypeError`:`name is not a function`
当你编写了一些非有效的JavaScript时,会抛出语法错误,例如当你把`return`这个词写成`retrun`时。
当JavaScript无法找到您尝试访问的值的引用时,抛出`ReferenceErrors`。
100. 输出什么?
// 🎉✨ This is my 100th question! ✨🎉
const output = `${[] && 'Im'}possible!
You should${'' && `n't`} see a therapist after so much JavaScript lol`
- A:
possible! You should see a therapist after so much JavaScript lol - B:
Impossible! You should see a therapist after so much JavaScript lol - C:
possible! You shouldn't see a therapist after so much JavaScript lol - D:
Impossible! You shouldn't see a therapist after so much JavaScript lol
我的:A(?) 正确:B
`[]`是一个真值。 使用`&&`运算符,如果左侧值是真值,则返回右侧值。 在这种情况下,左侧值`[]`是一个真值,所以返回`Im`。
`""`是一个假值。 如果左侧值是假的,则不返回任何内容。 `n't`不会被退回。
var result = [] && 'hello';
console.log(result); // hello
var result = '' && 'hello';
console.log(result); // ''
var result = ' ' && 'hello';
console.log(result); // hello
101.输出什么?
const one = (false || {} || null)
const two = (null || false || "")
const three = ([] || 0 || true)
console.log(one, two, three)
- A:
falsenull[] - B:
null""true - C:
{}""[] - D:
nullnulltrue
我的:? 正确:C
使用`||`运算符,我们可以返回第一个真值。 如果所有值都是假值,则返回最后一个值。
`(false || {} || null)`:空对象`{}`是一个真值。 这是第一个(也是唯一的)真值,它将被返回。`one`等于`{}`。
`(null || false ||“”)`:所有值都是假值。 这意味着返回传递的值`""`。 `two`等于`""`。
`([] || 0 ||“”)`:空数组`[]`是一个真值。 这是第一个返回的真值。 `three`等于`[]`。
function sayHello(name){
var name = name || 'jim'
console.log('hello ' + name)
}
var result = 1 || 2;
console.log(result); // 1
var result = undefined || 1;
console.log(result); // 1
var result = null || 1;
console.log(result); // 1
102. What’s the value of output?
const myPromise = () => Promise.resolve('I have resolved!')
function firstFunction() {
myPromise().then(res => console.log(res))
console.log('second')
}
async function secondFunction() {
console.log(await myPromise())
console.log('second')
}
firstFunction()
secondFunction()
- A:
I have resolved!,secondandI have resolved!,second - B:
second,I have resolved!andsecond,I have resolved! - C:
I have resolved!,secondandsecond,I have resolved! - D:
second,I have resolved!andI have resolved!,second
我的:B (error) 正确:D
With a promise, we basically say _I want to execute this function, but I'll put it aside for now while it's running since this might take a while. Only when a certain value is resolved (or rejected), and when the call stack is empty, I want to use this value._
We can get this value with both `.then` and the `await` keyword in an `async` function. Although we can get a promise's value with both `.then` and `await`, they work a bit differently.
In the `firstFunction`, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is `console.log('second')` in this case. Then, the function resolved with the string `I have resolved`, which then got logged after it saw that the callstack was empty.
With the await keyword in `secondFunction`, we literally pause the execution of an async function until the value has been resolved befoer moving to the next line.
This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged.
103. What’s the value of output?
const set = new Set()
set.add(1)
set.add("Lydia")
set.add({ name: "Lydia" })
for (let item of set) {
console.log(item + 2)
}
- A:
3,NaN,NaN - B:
3,7,NaN - C:
3,Lydia2,[Object object]2 - D:
"12",Lydia2,[Object object]2
我的:A (error) 正确:C
The `+` operator is not only used for adding numerical values, but we can also use it to concatenate strings. Whenever the JavaScript engine sees that one or more values are not a number, it coerces the number into a string.
The first one is `1`, which is a numerical value. `1 + 2` returns the number 3.
However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` is a number: `2` gets coerced into a string. `"Lydia"` and `"2"` get concatenated, which results in the string `"Lydia2"`.
`{ name: "Lydia" }` is an object. Neither a number nor an object is a string, so it stringifies both. Whenever we stringify a regular object, it becomes `"[Object object]"`. `"[Object object]"` concatenated with `"2"` becomes `"[Object object]2"`.
104. What’s its value?
Promise.resolve(5)
- A:
5 - B:
Promise {<pending>: 5} - C:
Promise {<resolved>: 5} - D:
Error
我的:C (ok)
105. What’s its value?
function compareMembers(person1, person2 = person) {
if (person1 !== person2) {
console.log("Not the same!")
} else {
console.log("They are the same!")
}
}
const person = { name: "Lydia" }
compareMembers(person)
- A:
Not the same! - B:
They are the same! - C:
ReferenceError - D:
SyntaxError
我的:B(ok)
106. What’s its value?
const colorConfig = {
red: true,
blue: false,
green: true,
black: true,
yellow: false,
}
const colors = ["pink", "red", "blue"]
console.log(colorConfig.colors[1])
- A:
true - B:
false - C:
undefined - D:
TypeError
我的:A (error) 正确:D
In JavaScript, we have two ways to access properties on an object: bracket notation, or dot notation. In this example, we use dot notation (`colorConfig.colors`) instead of bracket notation (`colorConfig["colors"]`).
With dot notation, JavaScript tries to find the property on the object with that exact name. In this example, JavaScript tries to find a property called `colors` on the `colorConfig` object. There is no proprety called `colors`, so this returns `undefined`. Then, we try to access the value of the first element by using `[1]`. We cannot do this on a value that's `undefined`, so it throws a `TypeError`: `Cannot read property '1' of undefined`.
JavaScript interprets (or unboxes) statements. When we use bracket notation, it sees the first opening bracket `[` and keeps going until it finds the closing bracket `]`. Only then, it will evaluate the statement. If we would've used `colorConfig[colors[1]]`, it would have returned the value of the `red` property on the `colorConfig` object.
107. What’s its value?
console.log('❤️' === '❤️')
- A:
true - B:
false
我的:A(ok)
108. Which of these methods modifies the original array?
const emojis = ['✨', '🥑', '😍']
emojis.map(x => x + '✨')
emojis.filter(x => x !== '🥑')
emojis.find(x => x !== '🥑')
emojis.reduce((acc, cur) => acc + '✨')
emojis.slice(1, 2, '✨')
emojis.splice(1, 2, '✨')
- A:
All of them - B:
mapreduceslicesplice - C:
mapslicesplice - D:
splice
我的:? 正确:D
With `splice` method, we modify the original array by deleting, replacing or adding elements. In this case, we removed 2 items from index 1 (we removed `'🥑'` and `'😍'`) and added the ✨ emoji instead.
`map`, `filter` and `slice` return a new array, `find` returns an element, and `reduce` returns a reduced value.
109. What’s the output?
const food = ['🍕', '🍫', '🥑', '🍔']
const info = { favoriteFood: food[0] }
info.favoriteFood = '🍝'
console.log(food)
- A:
['🍕', '🍫', '🥑', '🍔'] - B:
['🍝', '🍫', '🥑', '🍔'] - C:
['🍝', '🍕', '🍫', '🥑', '🍔'] - D:
ReferenceError
我的:A(ok)
110. What does this method do?
JSON.parse()
- A: Parses JSON to a JavaScript value
- B: Parses a JavaScript object to JSON
- C: Parses any JavaScript value to JSON
- D: Parses JSON to a JavaScript object only
我的:D(error) 正确:A
With the `JSON.parse()` method, we can parse JSON string to a JavaScript value.
```javascript
// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value:
const jsonNumber = JSON.stringify(4) // '4'
JSON.parse(jsonNumber) // 4
// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value:
const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]'
JSON.parse(jsonArray) // [1, 2, 3]
// Stringifying an object into valid JSON, then parsing the JSON string to a JavaScript value:
const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}'
JSON.parse(jsonArray) // { name: 'Lydia' }
111. What’s the output?
let name = 'Lydia'
function getName() {
console.log(name)
let name = 'Sarah'
}
getName()
- A: Lydia
- B: Sarah
- C:
undefined - D:
ReferenceError
我的:D(ok)
112. What’s the output?
function* generatorOne() {
yield ['a', 'b', 'c'];
}
function* generatorTwo() {
yield* ['a', 'b', 'c'];
}
const one = generatorOne()
const two = generatorTwo()
console.log(one.next().value)
console.log(two.next().value)
- A:
aanda - B:
aandundefined - C:
['a', 'b', 'c']anda - D:
aand['a', 'b', 'c']
我的:? 正确:C
With the `yield` keyword, we `yield` values in a generator function. With the `yield*` keyword, we can yield values from another generator function, or iterable object (for example an array).
In `generatorOne`, we yield the entire array `['a', 'b', 'c']` using the `yield` keyword. The value of `value` property on the object returned by the `next` method on `one` (`one.next().value`) is equal to the entire array `['a', 'b', 'c']`.
```javascript
console.log(one.next().value) // ['a', 'b', 'c']
console.log(one.next().value) // undefined
```
In `generatorTwo`, we use the `yield*` keyword. This means that the first yielded value of `two`, is equal to the first yielded value in the iterator. The iterator is the array `['a', 'b', 'c']`. The first yielded value is `a`, so the first time we call `two.next().value`, `a` is returned.
```javascript
console.log(two.next().value) // 'a'
console.log(two.next().value) // 'b'
console.log(two.next().value) // 'c'
console.log(two.next().value) // undefined
```
113. What’s the output?
console.log(`${(x => x)('I love')} to program`)
- A:
I love to program - B:
undefined to program - C:
${(x => x)('I love') to program - D:
TypeError
我的:A(ok)
Expressions within template literals are evaluated first. This means that the string will contain the returned value of the expression, the immediately invoked function `(x => x)('I love')` in this case. We pass the value `'I love'` as an argument to the `x => x` arrow function. `x` is equal to `'I love'`, which gets returned. This results in `I love to program`.
114. What will happen?
let config = {
alert: setInterval(() => {
console.log('Alert!')
}, 1000)
}
config = null
- A: The
setIntervalcallback won’t be invoked - B: The
setIntervalcallback gets invoked once - C: The
setIntervalcallback will still be called every second - D: We never invoked
config.alert(), config isnull
我的:D (error) 正确:C
Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s).
115. Which method(s) will return the value 'Hello world!'?
const myMap = new Map()
const myFunc = () => 'greeting'
myMap.set(myFunc, 'Hello world!')
//1
myMap.get('greeting')
//2
myMap.get(myFunc)
//3
myMap.get(() => 'greeting')
- A: 1
- B: 2
- C: 2 and 3
- D: All of them
我的:? 正确:B
When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => 'greeting'` in this case, and the value `'Hello world'`. `myMap` is now `{ () => 'greeting' => 'Hello world!' }`.
1 is wrong, since the key is not `'greeting'` but `() => 'greeting'`.
3 is wrong, since we're creating a new function by passing it as a parameter to the `get` method. Object interact by _reference_. Functions are objects, which is why two functions are never strictly equal, even if they are identical: they have a reference to a different spot in memory.
116. What’s the output?
const person = {
name: "Lydia",
age: 21
}
const changeAge = (x = { ...person }) => x.age += 1
const changeAgeAndName = (x = { ...person }) => {
x.age += 1
x.name = "Sarah"
}
changeAge(person)
changeAgeAndName()
console.log(person)
- A:
{name: "Sarah", age: 22} - B:
{name: "Sarah", age: 23} - C:
{name: "Lydia", age: 22} - D:
{name: "Lydia", age: 23}
我的:? 正确:C
Both the `changeAge` and `changeAgeAndName` functions have a default parameter, namely a _newly_ created object `{ ...person }`. This object has copies of all the key/values in the `person` object.
First, we invoke the `changeAge` function and pass the `person` object as its argument. This function increases the value of the `age` property by 1. `person` is now `{ name: "Lydia", age: 22 }`.
Then, we invoke the `changeAgeAndName` function, however we don't pass a parameter. Instead, the value of `x` is equal to a _new_ object: `{ ...person }`. Since it's a new object, it doesn't affect the values of the properties on the `person` object. `person` is still equal to `{ name: "Lydia", age: 22 }`.
处理代码:
var details = document.querySelectorAll('details');
var app = document.querySelector('#app')
for(let i = 0; i < details.length; i++){console.log(i)
app.removeChild(details[i])
}
More
javascript-questions
https://github.com/lydiahallie/javascript-questions