连云港建设公司网站,3d房屋设计软件手机版,怎么做网站营销策划,企业网站建设总体构架不定时更新
JavaScript 进阶问题列表
从基础到进阶#xff0c;测试你有多了解 JavaScript#xff0c;刷新你的知识#xff0c;或者帮助你的 coding 面试#xff01; #x1f4aa; #x1f680;
答案❤️ 1. 输出是什么#xff1f;
function sayHi() {console.log(na…不定时更新
JavaScript 进阶问题列表
从基础到进阶测试你有多了解 JavaScript刷新你的知识或者帮助你的 coding 面试
答案❤️ 1. 输出是什么
function sayHi() {console.log(name)console.log(age)var name Lydialet age 21
}sayHi()A: Lydia 和 undefinedB: Lydia 和 ReferenceErrorC: ReferenceError 和 21D: undefined 和 ReferenceError
答案 答案D
在函数内部我们首先通过 var 关键字声明了 name 变量。这意味着变量被提升了内存空间在创建阶段就被设置好了直到程序运行到定义变量位置之前默认值都是 undefined。因为当我们打印 name 变量时还没有执行到定义变量的位置因此变量的值保持为 undefined。
通过 let 和 const 关键字声明的变量也会提升但是和 var 不同它们不会被初始化。在我们声明初始化之前是不能访问它们的。这个行为被称之为暂时性死区。当我们试图在声明之前访问它们时JavaScript 将会抛出一个 ReferenceError 错误。 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 2B: 0 1 2 和 3 3 3C: 3 3 3 和 0 1 2
答案 答案C
由于 JavaScript 的事件循环setTimeout 回调会在遍历结束后才执行。因为在第一个遍历中遍历 i 是通过 var 关键字声明的所以这个值是全局作用域下的。在遍历过程中我们通过一元操作符 来每次递增 i 的值。当 setTimeout 回调执行的时候i 的值等于 3。
在第二个遍历中遍历 i 是通过 let 关键字声明的通过 let 和 const 关键字声明的变量是拥有块级作用域指的是任何在 {} 中的内容。在每次的遍历过程中i 都有一个新值并且每个值都在循环内的作用域中。 3. 输出是什么
const shape {radius: 10,diameter() {return this.radius * 2},perimeter: () 2 * Math.PI * this.radius
}shape.diameter()
shape.perimeter()A: 20 and 62.83185307179586B: 20 and NaNC: 20 and 63D: NaN and 63
答案 答案B
注意 diameter 的值是一个常规函数但是 perimeter 的值是一个箭头函数。
对于箭头函数this 关键字指向的是它当前周围作用域简单来说是包含箭头函数的常规函数如果没有常规函数的话就是全局对象这个行为和常规函数不同。这意味着当我们调用 perimeter 时this 不是指向 shape 对象而是它的周围作用域在例子中是 window。
在 window 中没有 radius 这个属性因此返回 undefined。 4. 输出是什么
true;
!Lydia;A: 1 and falseB: false and NaNC: false and false
答案 答案A
一元操作符加号尝试将 bool 转为 number。true 转换为 number 的话为 1false 为 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: 以上三个选项都是有效的
答案 答案A
在 JavaScript 中所有对象的 keys 都是字符串除非对象是 Symbol。尽管我们可能不会定义它们为字符串但它们在底层总会被转换为字符串。
当我们使用括号语法时[]JavaScript 会解释或者 unboxes语句。它首先看到第一个开始括号 [ 并继续前进直到找到结束括号 ]。只有这样它才会计算语句的值。
mouse[bird.size]首先计算 bird.size这会得到 small。mouse[small] 返回 true。
然后使用点语法的话上面这一切都不会发生。mouse 没有 bird 这个 key这也就意味着 mouse.bird 是 undefined。然后当我们使用点语法 mouse.bird.size 时因为 mouse.bird 是 undefined这也就变成了 undefined.size。这个行为是无效的并且会抛出一个错误类似 Cannot read property size of undefined。 6. 输出是什么
let c { greeting: Hey! }
let dd c
c.greeting Hello
console.log(d.greeting)A: HelloB: undefinedC: ReferenceErrorD: TypeError
答案 答案A
在 JavaScript 中当设置两个对象彼此相等时它们会通过引用进行交互。
首先变量 c 的值是一个对象。接下来我们给 d 分配了一个和 c 对象相同的引用。 因此当我们改变其中一个对象时其实是改变了所有的对象。 7. 输出是什么
let a 3
let b new Number(3)
let c 3console.log(a b)
console.log(a b)
console.log(b c)A: true false trueB: false false trueC: true false falseD: false true true
答案 答案C
new Number() 是一个内建的函数构造器。虽然它看着像是一个 number但它实际上并不是一个真实的 number它有一堆额外的功能并且它是一个对象。
当我们使用 操作符时它只会检查两者是否拥有相同的值。因为它们的值都是 3因此返回 true。
然后当我们使用 操作符时两者的值以及类型都应该是相同的。new Number() 是一个对象而不是 number因此返回 false。 8. 输出是什么
class Chameleon {static colorChange(newColor) {this.newColor newColorreturn this.newColor}constructor({ newColor green } {}) {this.newColor newColor}
}const freddie new Chameleon({ newColor: purple })
freddie.colorChange(orange)A: orangeB: purpleC: greenD: TypeError
答案 答案D
colorChange 是一个静态方法。静态方法被设计为只能被创建它们的构造器使用也就是 Chameleon并且不能传递给实例。因为 freddie 是一个实例静态方法不能被实例使用因此抛出了 TypeError 错误。 9. 输出是什么
let greeting
greetign {} // Typo!
console.log(greetign)A: {}B: ReferenceError: greetign is not definedC: undefined
答案 答案A
代码打印出了一个对象这是因为我们在全局对象上创建了一个空对象当我们将 greeting 写错成 greetign 时JS 解释器实际在上浏览器中将它视为 global.greetign {}或者 window.greetign {}。
为了避免这个为题我们可以使用 “use strict”。这能确保当你声明变量时必须赋值。 10. 当我们这么做时会发生什么
function bark() {console.log(Woof!)
}bark.animal dogA: 正常运行B: SyntaxError. 你不能通过这种方式给函数增加属性。C: undefinedD: ReferenceError
答案 答案A
这在 JavaScript 中是可以的因为函数是对象除了基本类型之外其他都是对象
函数是一个特殊的对象。你写的这个代码其实不是一个实际的函数。函数是一个拥有属性的对象并且属性也可被调用。 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: TypeErrorB: SyntaxErrorC: Lydia HallieD: undefined undefined
答案 答案A
你不能像常规对象那样给构造函数添加属性。如果你想一次性给所有实例添加特性你应该使用原型。因此本例中使用如下方式
Person.prototype.getFullName function () {return ${this.firstName} ${this.lastName};
}这才会使 member.getFullName() 起作用。为什么这么做有益的假设我们将这个方法添加到构造函数本身里。也许不是每个 Person 实例都需要这个方法。这将浪费大量内存空间因为它们仍然具有该属性这将占用每个实例的内存空间。相反如果我们只将它添加到原型中那么它只存在于内存中的一个位置但是所有实例都可以访问它 12. 输出是什么
function Person(firstName, lastName) {this.firstName firstNamethis.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} and undefinedB: Person {firstName: Lydia, lastName: Hallie} and Person {firstName: Sarah, lastName: Smith}C: Person {firstName: Lydia, lastName: Hallie} and {}D:Person {firstName: Lydia, lastName: Hallie} and ReferenceError
答案 答案A
对于 sarah我们没有使用 new 关键字。当使用 new 时this 引用我们创建的空对象。当未使用 new 时this 引用的是全局对象global object。
我们说 this.firstName 等于 Sarah并且 this.lastName 等于 Smith。实际上我们做的是定义了 global.firstName Sarah 和 global.lastName Smith。而 sarah 本身是 undefined。 13. 事件传播的三个阶段是什么
A: Target Capturing BubblingB: Bubbling Target CapturingC: Target Bubbling CapturingD: Capturing Target Bubbling
答案 答案D
在捕获capturing阶段中事件从祖先元素向下传播到目标元素。当事件达到目标target元素后冒泡bubbling才开始。 14. 所有对象都有原型。
A: 对B: 错
答案 答案B
除了基本对象base object所有对象都有原型。基本对象可以访问一些方法和属性比如 .toString。这就是为什么你可以使用内置的 JavaScript 方法所有这些方法在原型上都是可用的。虽然 JavaScript 不能直接在对象上找到这些方法但 JavaScript 会沿着原型链找到它们以便于你使用。 15. 输出是什么
function sum(a, b) {return a b
}sum(1, 2)A: NaNB: TypeErrorC: 12D: 3
答案 答案C
JavaScript 是一种动态类型语言我们不指定某些变量的类型。值可以在你不知道的情况下自动转换成另一种类型这种类型称为隐式类型转换implicit type coercion。Coercion 是指将一种类型转换为另一种类型。
在本例中JavaScript 将数字 1 转换为字符串以便函数有意义并返回一个值。在数字类型1和字符串类型2相加时该数字被视为字符串。我们可以连接字符串比如 Hello World这里发生的是 1 2它返回 12。 16. 输出是什么
let number 0
console.log(number)
console.log(number)
console.log(number)A: 1 1 2B: 1 2 2C: 0 2 2D: 0 1 2
答案 答案C
一元后自增运算符
返回值返回 0值自增number 现在是 1
一元前自增运算符
值自增number 现在是 2返回值返回 2
结果是 0 2 2. 17. 输出是什么
function getPersonInfo(one, two, three) {console.log(one)console.log(two)console.log(three)
}const person Lydia
const age 21getPersonInfo${person} is ${age} years oldA: Lydia 21 [, is , years old]B: [, is , years old] Lydia 21C: 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 dont have an age I guess)}
}checkAge({ age: 18 })A: You are an adult!B: You are still an adult.C: Hmm.. You dont have an age I guess
答案 答案C
在测试相等性时基本类型通过它们的值value进行比较而对象通过它们的引用reference进行比较。JavaScript 检查对象是否具有对内存中相同位置的引用。
题目中我们正在比较的两个对象不是同一个引用作为参数传递的对象引用的内存位置与用于判断相等的对象所引用的内存位置并不同。
这也是 { age: 18 } { age: 18 } 和 { age: 18 } { age: 18 } 都返回 false 的原因。 19. 输出是什么
function getAge(...args) {console.log(typeof args)
}getAge(21)A: numberB: arrayC: objectD: NaN
答案 答案C
扩展运算符...args会返回实参组成的数组。而数组是对象因此 typeof args 返回 object。 20. 输出是什么
function getAge() {use strictage 21console.log(age)
}getAge()A: 21B: undefinedC: ReferenceErrorD: TypeError
答案 答案C
使用 use strict你可以确保不会意外地声明全局变量。我们从来没有声明变量 age因为我们使用 use strict它将抛出一个引用错误。如果我们不使用 use strict它就会工作因为属性 age 会被添加到全局对象中了。 21. 输出是什么
const sum eval(10*105)A: 105B: 105C: TypeErrorD: 10*105
答案 答案A
代码以字符串形式传递进来eval 对其求值。如果它是一个表达式就像本例中那样它对表达式求值。表达式是 10 * 10 5。这将返回数字 105。 22. cool_secret 可访问多长时间
sessionStorage.setItem(cool_secret, 123)A: 永远数据不会丢失。B: 当用户关掉标签页时。C: 当用户关掉整个浏览器而不只是关掉标签页。D: 当用户关闭电脑时。
答案 答案B
关闭 tab 标签页 后sessionStorage 存储的数据才会删除。
如果使用 localStorage那么数据将永远在那里除非调用了 localStorage.clear()。 23. 输出是什么
var num 8
var num 10console.log(num)A: 8B: 10C: SyntaxErrorD: 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 trueB: false true true trueC: true true false trueD: true true true true
答案 答案C
所有对象的键不包括 Symbol在底层都是字符串即使你自己没有将其作为字符串输入。这就是为什么 obj.hasOwnProperty(1) 也返回 true。
对于集合它不是这样工作的。在我们的集合中没有 1set.has(1) 返回 false。它有数字类型为 1set.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) continueconsole.log(i)
}A: 1 2B: 1 2 3C: 1 2 4D: 1 3 4
答案 答案C
如果某个条件返回 true则 continue 语句跳过本次迭代。 28. 输出是什么
String.prototype.giveLydiaPizza () {return Just give Lydia pizza already!
}const name Lydianame.giveLydiaPizza()A: Just give Lydia pizza already!B: TypeError: not a functionC: SyntaxErrorD: undefined
答案 答案A
String 是内置的构造函数我们可以向它添加属性。我只是在它的原型中添加了一个方法。基本类型字符串被自动转换为字符串对象由字符串原型函数生成。因此所有 string(string 对象) 都可以访问该方法 29. 输出是什么
const a {}
const b { key: b }
const c { key: c }a[b] 123
a[c] 456console.log(a[b])A: 123B: 456C: undefinedD: ReferenceError
答案 答案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: First Second ThirdB: First Third SecondC: Second First ThirdD: Second Third First
答案 答案B
我们有一个 setTimeout 函数并首先调用它。然而它是最后打印日志的。
这是因为在浏览器中我们不仅有运行时引擎还有一个叫做 WebAPI 的东西。WebAPI 提供了 setTimeout 函数也包含其他的例如 DOM。
将 callback 推送到 WebAPI 后setTimeout 函数本身 (但不是回调) 将从栈中弹出。 现在foo 被调用打印 First。 foo 从栈中弹出baz 被调用。打印 Third。 WebAPI 不能随时向栈内添加内容。相反它将回调函数推到名为 queue 的地方。 这就是事件循环开始工作的地方。一个事件循环查看栈和任务队列。如果栈是空的它接受队列上的第一个元素并将其推入栈。 bar 被调用打印 Second然后它被栈弹出。 31. 当点击按钮时event.target 是什么
div onclickconsole.log(first div)div onclickconsole.log(second div)button onclickconsole.log(button)Click!/button/div
/divA: Outer divB: Inner divC: buttonD: 一个包含所有嵌套元素的数组。
答案 答案C
导致事件的最深嵌套的元素是事件的 target。你可以通过 event.stopPropagation 来停止冒泡。 32. 当您单击该段落时日志输出是什么
div onclickconsole.log(div)p onclickconsole.log(p)Click here!/p
/divA: p divB: div pC: pD: div
答案 答案A
如果我们点击 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 21 Lydia is 21B: function functionC: Lydia is 21 Lydia is 21D: Lydia is 21 function
答案 答案D
使用这两种方法我们都可以传递我们希望 this 关键字引用的对象。但是.call 是立即执行的。
.bind 返回函数的副本但带有绑定上下文它不是立即执行的。 34. 输出是什么
function sayHi() {return (() 0)()
}typeof sayHi()A: objectB: numberC: functionD: undefined
答案 答案B
sayHi 方法返回的是立即执行函数 (IIFE) 的返回值。此立即执行函数的返回值是 0类型是 number
参考只有 7 种内置类型nullundefinedbooleannumberstringobject, symbol 和 bigint。function 不是一种类型函数是对象它的类型是object。 35. 下面哪些值是 falsy?
0
new Number(0)
()
( )
new Boolean(false)
undefinedA: 0, , undefinedB: 0, new Number(0), , new Boolean(false), undefinedC: 0, , new Boolean(false), undefinedD: All of them are falsy
答案 答案A
只有 8 种 falsy 值
undefinednullNaNfalse (empty string)0-00n (BigInt(0))
Function 构造函数比如 new Number 和 new Boolean是 truthy。 36. 输出是什么
console.log(typeof typeof 1)A: numberB: stringC: objectD: undefined
答案 答案B
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
答案 答案C
当你为数组设置超过数组长度的值的时候JavaScript 会创建名为 “empty slots” 的东西。它们的值实际上是 undefined。你会看到以下场景
[1, 2, 3, 7 x empty, 11]
这取决于你的运行环境每个浏览器以及 node 环境都有可能不同 38. 输出是什么
(() {let x, ytry {throw new Error()} catch (x) {(x 1), (y 2)console.log(x)}console.log(x)console.log(y)
})()A: 1 undefined 2B: undefined undefined undefinedC: 1 1 2D: 1 undefined undefined
答案 答案A
catch 代码块接收参数 x。当我们传递参数时这与之前定义的变量 x 不同。这个 x 是属于 catch 块级作用域的。
然后我们将块级作用域中的变量赋值为 1同时也设置了变量 y 的值。现在我们打印块级作用域中的变量 x值为 1。
catch 块之外的变量 x 的值仍为 undefinedy 的值为 2。当我们在 catch 块之外执行 console.log(x) 时返回 undefinedy 返回 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
[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
!!
!!1A: false true falseB: false false trueC: false true trueD: true true false
答案 答案B
null 是 falsy。!null 的值是 true。!true 的值是 false。 是 falsy。! 的值是 true。!true 的值是 false。
1 是 truthy。!1 的值是 false。!false 的值是 true。 42. setInterval 方法的返回值是什么
setInterval(() console.log(Hi), 1000)A: 一个唯一的 idB: 该方法指定的毫秒数C: 传递的函数D: undefined
答案 答案A
setInterval 返回一个唯一的 id。此 id 可被用于 clearInterval 函数来取消定时。 43. 输出是什么
[...Lydia]A: [L, y, d, i, a]B: [Lydia]C: [[], Lydia]D: [[L, y, d, i, 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, 20C: 10, 20D: 0, 10 and 10, 20
答案 答案C
一般的函数在执行之后是不能中途停下的。但是生成器函数却可以中途“停下”之后可以再从停下的地方继续。当生成器遇到yield关键字的时候会生成yield后面的值。注意生成器在这种情况下不 返回 (return ) 值而是 生成 (yield) 值。
首先我们用10作为参数i来初始化生成器函数。然后使用next()方法一步步执行生成器。第一次执行生成器的时候i的值为10遇到第一个yield关键字它要生成i的值。此时生成器“暂停”生成了10。
然后我们再执行next()方法。生成器会从刚才暂停的地方继续这个时候i还是10。于是我们走到了第二个yield关键字处这时候需要生成的值是i*2i为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: oneB: twoC: two oneD: 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: nullB: [null]C: [{}]D: [{ name: Lydia }]
答案 答案D
首先我们声明了一个拥有name属性的对象 person。 然后我们又声明了一个变量members. 将首个元素赋值为变量person。当设置两个对象彼此相等时它们会通过 引用 进行交互。但是当你将引用从一个变量分配至另一个变量时其实只是执行了一个 复制 操作。注意一点他们的引用 并不相同! 接下来我们让person等于null。 我们没有修改数组第一个元素的值而只是修改了变量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, ageC: Lydia, 21D: [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: 345B: 75C: 12D: 12
答案 答案B
当所有运算符的 优先级 相同时计算表达式需要确定运算符的结合顺序即从右到左还是从左往右。在这个例子中我们只有一类运算符对于加法来说结合顺序就是从左到右。
3 4首先计算得到数字7.
由于类型的强制转换7 5的结果是75. JavaScript 将7转换成了字符串可以参考问题 15.我们可以用号把两个字符串连接起来。7 5 就得到了75. 49. num的值是什么
const num parseInt(7*6, 10);A: 42B: 42C: 7D: NaN
答案 答案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
对数组进行映射的时候num就是当前循环到的元素。在这个例子中所有的映射都是 number 类型所以 if 中的判断typeof num number结果都是true.map 函数创建了新数组并且将函数的返回值插入数组。
但是没有任何值返回。当函数没有返回任何值时即默认返回undefined.对数组中的每一个元素来说函数块都得到了这个返回值所以结果中每一个元素都是undefined. 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 }, 1997B: { name: Sarah }, 1998C: { name: Lydia }, 1998D: { name: Sarah }, 1997
答案 答案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: undefinedC: SyntaxError: can only throw Error objectsD: Oh no an error: Hello world!
答案 答案D
通过throw语句我么可以创建自定义错误。而通过它我们可以抛出异常。异常可以是一个字符串一个 数字一个 布尔类型 或者是一个 对象。在本例中我们的异常是字符串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: LamborghiniB: MaseratiC: ReferenceErrorD: TypeError
答案 答案B
返回属性的时候属性的值等于 返回的 值而不是构造函数中设定的值。我们返回了字符串 Maserati所以 myCar.make等于Maserati. 54. 输出是什么
(() {let x (y 10);
})();console.log(typeof x);
console.log(typeof y);A: undefined, numberB: number, numberC: object, numberD: number, undefined
答案 答案A
let x y 10; 是下面这个表达式的缩写
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, TypeErrorB: Woof I am Mara,Woof I am MaraC: Woof I am Mara, undefinedD: TypeError, TypeError
答案 答案A
我们可以用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}
答案 答案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: 10B: 11C: ErrorD: NaN
答案 答案C
引入的模块是 只读 的你不能修改引入的模块。只有导出他们的模块才能修改其值。
当我们给myCounter增加一个值的时候会抛出一个异常myCounter是只读的不能被修改。 58. 输出是什么
const name Lydia;
age 21;console.log(delete name);
console.log(delete age);A: false, trueB: Lydia, 21C: true, trueD: 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: 1D: [1]
答案 答案C
我们可以通过解构赋值来解析来自对象的数组或属性的值比如说
[a, b] [1, 2];a的值现在是1b的值现在是2.而在题目中我们是这么做的
[y] [1, 2, 3, 4, 5];也就是说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
扩展运算符...为对象的组合提供了可能。你可以复制对象中的键值对然后把它们加到另一个对象里去。在本例中我们复制了user对象键值对然后把它们加入到admin对象中。admin对象就拥有了这些键值对所以结果为{ admin: true, name: Lydia, age: 21 }. 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]
答案 答案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
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, 10B: 10, 11C: 11, 11D: 11, 12
答案 答案A
一元操作符 先返回 操作值再累加 操作值。num1的值是10因为increaseNumber函数首先返回num的值也就是10随后再进行 num的累加。
num2是10因为我们将 num1传入increasePassedNumber. number等于10num1的值。同样道理 先返回 操作值再累加 操作值。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, 160B: 20, 40, 20, 40C: 20, 20, 20, 40D: NaN, NaN, 20, 40
答案 答案C
在 ES6 中我们可以使用默认值初始化参数。如果没有给函数传参或者传的参值为 undefined那么参数的值将是默认值。上述例子中我们将 value 对象进行了解构并传到一个新对象中因此 x 的默认值为 {number10}。
默认参数在调用时才会进行计算每次调用函数时都会创建一个新的对象。我们前两次调用 multiply 函数且不传递值那么每一次 x 的默认值都为 {number10}因此打印出该数字的乘积值为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: 1 2 and 3 3 and 6 4B: 1 2 and 2 3 and 3 4C: 1 undefined and 2 undefined and 3 undefined and 4 undefinedD: 1 2 and undefined 3 and undefined 4
答案 答案D
reducer 函数接收 4 个参数
Accumulator (acc) (累计器)Current Value (cur) (当前值)Current Index (idx) (当前索引)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;}// 2constructor(name, size) {super(name);this.size size;}// 3constructor(size) {super(name);this.size size;}// 4 constructor(name, size) {this.name name;this.size size;}};A: 1B: 2C: 3D: 4
答案 答案B
在子类中在调用super之前不能访问到this关键字。如果这样做它将抛出一个ReferenceError1 和 4 将引发一个引用错误。
使用super关键字需要用给定的参数来调用父类的构造函数。父类的构造函数接收name参数因此我们需要将name传递给super。
Labrador类接收两个参数name参数是由于它继承了Dogsize作为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, 3B: running sum.js, running index.js, 3C: running sum.js, 3, running index.jsD: running index.js, undefined, running sum.js
答案 答案B
import命令是编译阶段执行的在代码运行之前。因此这意味着被导入的模块会先运行而导入模块的文件会后执行。
这是 CommonJS 中require和import之间的区别。使用require()您可以在运行代码时根据需要加载依赖项。如果我们使用require而不是importrunning index.jsrunning sum.js3会被依次打印。 68. 输出什么
console.log(Number(2) Number(2))
console.log(Boolean(false) Boolean(false))
console.log(Symbol(foo) Symbol(foo))A: true, true, falseB: false, true, falseC: true, false, trueD: true, true, true
答案 答案A
每个Symbol都是完全唯一的。传递给Symbol的参数只是给Symbol的一个描述。Symbol的值不依赖于传递的参数。当我们测试相等时我们创建了两个全新的符号第一个Symbolfoo第二个Symbolfoo这两个值是唯一的彼此不相等因此返回false。 69. 输出什么
const name Lydia Hallie
console.log(name.padStart(13))
console.log(name.padStart(2))A: Lydia Hallie, Lydia HallieB: 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
使用padStart方法我们可以在字符串的开头添加填充。传递给此方法的参数是字符串的总长度包含填充。字符串Lydia Hallie的长度为12因此name.padStart13在字符串的开头只会插入 113 - 12 1个空格。
如果传递给padStart方法的参数小于字符串的长度则不会添加填充。 70. 输出什么
console.log( );A: B: 257548C: A string containing their code pointsD: Error
答案 答案A
使用运算符您可以连接字符串。上述情况我们将字符串“”与字符串”“连接起来产生”“。 71. 如何能打印出console.log语句后注释掉的值
function* startGame() {const 答案 yield Do you love JavaScript?;if (答案 ! Yes) {return Oh wow... Guess were 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).value and game.next().valueB: game.next.value(Yes) and game.next.value()C: game.next().value and game.next(Yes).valueD: game.next.value() and game.next.value(Yes)
答案 答案C
generator函数在遇到yield关键字时会“暂停”其执行。首先我们需要让函数产生字符串Do you love JavaScript?这可以通过调用game.next().value来完成。上述函数的第一行就有一个yield关键字那么运行立即停止了yield表达式本身没有返回值或者说总是返回undefined这意味着此时变量 答案 为undefined
next方法可以带一个参数该参数会被当作上一个 yield 表达式的返回值。当我们调用game.next(Yes).value时先前的 yield 的返回值将被替换为传递给next()函数的参数Yes。此时变量 答案 被赋值为 Yesif语句返回false所以JavaScript loves you back ❤️被打印。 72. 输出什么
console.log(String.rawHello\nworld);A: Hello world!B: Hello worldC: Hello\nworldD: Hello\n world
答案 答案C
String.raw函数是用来获取一个模板字符串的原始字符串的它返回一个字符串其中忽略了转义符\n\v\t等。但反斜杠可能造成问题因为你可能会遇到下面这种类似情况
const path C:\Documents\Projects\table.html
String.raw${path}这将导致
C:DocumentsProjects able.html
直接使用String.raw
String.rawC:\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: 2C: trueD: undefined
答案 答案B
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
答案 答案B
Object.freeze使得无法添加、删除或修改对象的属性除非属性的值是另一个对象。
当我们创建变量shape并将其设置为等于冻结对象box时shape指向的也是冻结对象。你可以使用Object.isFrozen检查一个对象是否被冻结上述情况Object.isFrozenshape将返回true。
由于shape被冻结并且x的值不是对象所以我们不能修改属性x。x仍然等于10{x10y20}被打印。
注意上述例子我们对属性x进行修改可能会导致抛出 TypeError 异常最常见但不仅限于严格模式下时。 76. 输出什么
const { name: myName } { name: Lydia };console.log(name);A: LydiaB: myNameC: undefinedD: ReferenceError
答案 答案D
当我们从右侧的对象解构属性name时我们将其值Lydia分配给名为myName的变量。
使用{namemyName}我们是在告诉 JavaScript 我们要创建一个名为myName的新变量并且其值是右侧对象的name属性的值。
当我们尝试打印name一个未定义的变量时就会引发ReferenceError。 77. 以下是个纯函数么
function sum(a, b) {return a b;
}A: YesB: No
答案 答案A
纯函数在相同的输入值时需产生相同的输出其输出的结果与输入值以外的其他隐藏信息或状态无关也和由 I/O 设备产生的外部输出无关。 纯函数不会产生副作用。
纯函数与副作用的定义可参考 https://zh.wikipedia.org/wiki/%E5%89%AF%E4%BD%9C%E7%94%A8_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6) 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! 20 Calculated! 20 Calculated! 20B: Calculated! 20 From cache! 20 Calculated! 20C: Calculated! 20 From cache! 20 From cache! 20D: Calculated! 20 From cache! 20 Error
答案 答案C
add函数是一个记忆函数。通过记忆化我们可以缓存函数的结果以加快其执行速度。上述情况我们创建一个cache对象用于存储先前返回过的值。
如果我们使用相同的参数多次调用addFunction函数它首先检查缓存中是否已有该值如果有则返回缓存值这将节省执行时间。如果没有那么它将计算该值并存储在缓存中。
我们用相同的值三次调用了addFunction函数
在第一次调用num等于10时函数的值尚未缓存if 语句num in cache返回falseelse 块的代码被执行Calculated! 20并且其结果被添加到缓存对象cache现在看起来像{10:20}。
第二次cache对象包含10的返回值。if 语句 num in cache 返回trueFrom cache! 20被打印。
第三次我们将5 * 2(值为 10) 传递给函数。cache对象包含10的返回值。if 语句 num in cache 返回trueFrom cache! 20被打印。 79. 输出什么
const myLifeSummedUp [☕, , , ]for (let item in myLifeSummedUp) {console.log(item)
}for (let item of myLifeSummedUp) {console.log(item)
}A: 0 1 2 3 and ☕ B: ☕ and ☕ C: ☕ and 0 1 2 3D: 0 1 2 3 and {0: ☕, 1: , 2: , 3: }
答案 答案A
通过for-in循环我们可以遍历一个对象自有的、继承的、可枚举的、非 Symbol 的属性。在数组中可枚举属性是数组元素的“键”即它们的索引。类似于下面这个对象
{0: ☕, 1: , 2: , 3: }
其中键则是可枚举属性因此 0123被记录。
通过for-of循环我们可以迭代可迭代对象包括 ArrayMapSetStringarguments等。当我们迭代数组时在每次迭代中不同属性的值将被分配给变量item因此“☕”“”“”“”被打印。 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
数组元素可以包含任何值。数字字符串布尔值对象数组nullundefined以及其他表达式如日期函数和计算。
元素将等于返回的值。1 2返回31 * 2返回’21 / 2返回0.5。 81. 输出什么
function sayHi(name) {return Hi there, ${name}
}console.log(sayHi())A: Hi there, B: Hi there, undefinedC: Hi there, nullD: ReferenceError
答案 答案B
默认情况下如果不给函数传参参数的值将为undefined。上述情况我们没有给参数name传值。name等于undefined并被打印。
在 ES6 中我们可以使用默认参数覆盖此默认的undefined值。例如
function sayHi (name “Lydia”){...}
在这种情况下如果我们没有传递值或者如果我们传递undefinedname总是等于字符串Lydia 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
答案 答案B
this关键字的指向取决于使用它的位置。在函数中比如getStatusthis指向的是调用它的对象上述例子中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 Amsterdamconsole.log(person)A: { name: Lydia, age: 21 }B: { name: Lydia, age: 21, city: Amsterdam }C: { name: Lydia, age: 21, city: undefined }D: Amsterdam
答案 答案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, youre too young.} else {const message Yay! Youre old enough!}return message
}console.log(checkAge(21))A: Sorry, youre too young.B: Yay! Youre old enough!C: ReferenceErrorD: undefined
答案 答案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: !!nameB: nameC: new Boolean(name)D: name.length
答案 答案A
使用逻辑非运算符!将返回一个布尔值使用!! name我们可以确定name的值是真的还是假的。如果name是真实的那么!name返回false。!false返回true。
通过将hasName设置为name可以将hasName设置为等于传递给getName函数的值而不是布尔值true。
new Booleantrue返回一个对象包装器而不是布尔值本身。
name.length返回传递的参数的长度而不是布尔值true。
87. 输出什么
console.log(I want pizza[0])A: B: IC: SyntaxErrorD: undefined
答案 答案B
可以使用方括号表示法获取字符串中特定索引的字符字符串中的第一个字符具有索引 0依此类推。在这种情况下我们想要得到索引为 0 的元素字符I被记录。
请注意IE7 及更低版本不支持此方法。在这种情况下应该使用.charAt 88. 输出什么
function sum(num1, num2 num1) {console.log(num1 num2)
}sum(10)A: NaNB: 20C: ReferenceErrorD: undefined
答案 答案B
您可以将默认参数的值设置为函数的另一个参数只要另一个参数定义在其之前即可。我们将值10传递给sum函数。如果sum函数只接收 1 个参数则意味着没有传递num2的值这种情况下num1的值等于传递的值10。num2的默认值是num1的值即10。num1 num2返回20。
如果您尝试将默认参数的值设置为后面定义的参数则可能导致参数的值尚未初始化从而引发错误。比如
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 489. 输出什么
// module.js
export default () Hello world
export const name Lydia// index.js
import * as data from ./moduleconsole.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
使用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: classB: functionC: objectD: string
答案 答案C
类是构造函数的语法糖如果用构造函数的方式来重写Person类则将是
function Person() {this.name name
}通过new来调用构造函数将会生成构造函数Person的实例对实例执行typeof关键字将返回object上述情况打印出object。 91. 输出什么
let newList [1, 2, 3].push(4)console.log(newList.push(5))A: [1, 2, 3, 4, 5]B: [1, 2, 3, 5]C: [1, 2, 3, 4]D: Error
答案 答案D
.push方法返回数组的长度而不是数组本身通过将newList设置为[1,2,3].push(4)实际上newList等于数组的新长度4。
然后尝试在newList上使用.push方法。由于newList是数值4抛出 TypeError。 92. 输出什么
function giveLydiaPizza() {return Here is pizza!
}const giveLydiaChocolate () Heres 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
答案 答案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: name Lydia and age 21B: [name, Lydia] and [age, 21]C: [name, age] and undefinedD: Error
答案 答案A
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组上述情况返回一个二维数组数组每个元素是一个包含键和值的数组
[[name,Lydia],[age, 21]]
使用for-of循环我们可以迭代数组中的每个元素上述情况是子数组。我们可以使用const [xy]在for-of循环中解构子数组。x等于子数组中的第一个元素y等于子数组中的第二个元素。
第一个子阵列是[“name”“Lydia”]其中x等于name而y等于Lydia。 第二个子阵列是[“age”21]其中x等于age而y等于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是剩余参数剩余参数的值是一个包含所有剩余参数的数组并且只能作为最后一个参数。上述示例中剩余参数是第二个参数这是不可能的并会抛出语法错误。
function getItems(fruitList, favoriteFruit, ...args) {return [...fruitList, ...args, favoriteFruit]
}getItems([banana, apple], pear, orange)上述例子是有效的将会返回数组[ banana, apple, orange, pear ] 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, 6 and b is bigger, 3B: a is bigger, undefined and b is bigger, undefinedC: undefined and undefinedD: SyntaxError
答案 答案B
在 JavaScript 中我们不必显式地编写分号 (;)但是 JavaScript 引擎仍然在语句之后自动添加分号。这称为自动分号插入。例如一个语句可以是变量或者像throw、return、break这样的关键字。
在这里我们在新的一行上写了一个return语句和另一个值a b 。然而由于它是一个新行引擎并不知道它实际上是我们想要返回的值。相反它会在return后面自动添加分号。你可以这样看 return;a b这意味着永远不会到达a b因为函数在return关键字之后停止运行。如果没有返回值就像这里函数返回undefined。注意在if/else语句之后没有自动插入 96. 输出什么
class Person {constructor() {this.name Lydia}
}Person class AnotherPerson {constructor() {this.name Sarah}
}const member new Person()
console.log(member.name)A: LydiaB: SarahC: Error: cannot redeclare PersonD: SyntaxError
答案 答案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
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]] and SyntaxErrorB: [1, [2, 3, 4]] and { name: Lydia, age: 21 }C: [1, 2, 3, 4] and { name: Lydia, age: 21 }D: Error and { name: Lydia, age: 21 }
答案 答案A
getList函数接收一个数组作为其参数。在getList函数的括号之间我们立即解构这个数组。您可以将其视为
[x, ...y] [1, 2, 3, 4]
使用剩余的参数... y我们将所有剩余参数放在一个数组中。在这种情况下其余的参数是23和4。 y的值是一个数组包含所有其余参数。在这种情况下x的值等于1所以当我们打印[xy]时会打印[1[2,3,4]]。
getUser函数接收一个对象。对于箭头函数如果只返回一个值我们不必编写花括号。但是如果您想从一个箭头函数返回一个对象您必须将它写在圆括号之间否则两个花括号之间的所有内容都将被解释为一个块语句在这种情况下花括号之间的代码不是有效的 JavaScript 代码因此会抛出 SyntaxError。
以下函数将返回一个对象
const getUser user ({ name: user.name, age: user.age }) 99. 输出什么
const name Lydiaconsole.log(name())A: SyntaxErrorB: ReferenceErrorC: TypeErrorD: undefined
答案 答案C
变量name保存字符串的值该字符串不是函数因此无法调用。
当值不是预期类型时会抛出TypeErrors。JavaScript 期望name是一个函数因为我们试图调用它。但它是一个字符串因此抛出TypeErrorname is not a function
当你编写了一些非有效的 JavaScript 时会抛出语法错误例如当你把return这个词写成retrun时。 当 JavaScript 无法找到您尝试访问的值的引用时抛出ReferenceErrors。 100. 输出什么
// ✨ This is my 100th question! ✨const output ${[] Im}possible!
You should${ nt} see a therapist after so much JavaScript lolA: possible! You should see a therapist after so much JavaScript lolB: Impossible! You should see a therapist after so much JavaScript lolC: possible! You shouldnt see a therapist after so much JavaScript lolD: Impossible! You shouldnt see a therapist after so much JavaScript lol
答案 答案B
[]是一个真值。使用运算符如果左侧值是真值则返回右侧值。在这种情况下左侧值[]是一个真值所以返回Im。
是一个假值。如果左侧值是假的则不返回任何内容。nt不会被退回。 101.输出什么
const one (false || {} || null)
const two (null || false || )
const three ([] || 0 || true)console.log(one, two, three)A: false null []B: null trueC: {} []D: null null true
答案 答案C
使用||运算符我们可以返回第一个真值。如果所有值都是假值则返回最后一个值。
false || {} || null空对象{}是一个真值。这是第一个也是唯一的真值它将被返回。one等于{}。
null || false ||“”所有值都是假值。这意味着返回传递的值。two等于。
[] || 0 ||“”空数组[]是一个真值。这是第一个返回的真值。three等于[]。 102. 依次输出什么
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!, second and I have resolved!, secondB: second, I have resolved! and second, I have resolved!C: I have resolved!, second and second, I have resolved!D: second, I have resolved! and I have resolved!, second
答案 答案D
有了 promise我们通常会说当我想要调用某个方法但是由于它可能需要一段时间因此暂时将它放在一边。只有当某个值被 resolved/rejected并且执行栈为空时才使用这个值。
我们可以在async函数中通过.then和await关键字获得该值。尽管我们可以通过.then和await获得 promise 的价值但是它们的工作方式有所不同。
在 firstFunction中当运行到myPromise方法时我们将其放在一边即 promise 进入微任务队列其他后面的代码console.log(second)照常运行因此second被打印出firstFunction方法到此执行完毕执行栈中宏任务队列被清空此时开始执行微任务队列中的任务I have resolved被打印出。
在secondFunction方法中我们通过await关键字暂停了后面代码的执行直到异步函数的值被解析才开始后面代码的执行。这意味着它会等着直到 myPromise 以值I have resolved被解决之后下一行second才开始执行。 103. 输出什么
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, NaNB: 3, 7, NaNC: 3, Lydia2, [Object object]2D: 12, Lydia2, [Object object]2
答案 答案C
“”运算符不仅用于添加数值还可以使用它来连接字符串。每当 JavaScript 引擎发现一个或多个值不是数字时就会将数字强制为字符串。
第一个是数字 1。1 2 返回数字 3。
但是第二个是字符串“Lydia”。 “Lydia”是一个字符串2 是一个数字2 被强制转换为字符串。 “Lydia”和“2”被连接起来产生字符串“Lydia2”。
{name“Lydia”}是一个对象。数字和对象都不是字符串因此将二者都字符串化。每当我们对常规对象进行字符串化时它就会变成[Object object]。与“2”串联的“ [Object object]”成为“[Object object]2”。 104. 结果是什么
Promise.resolve(5)A: 5B: Promise {pending: 5}C: Promise {fulfilled: 5}D: Error
答案 答案C
我们可以将我们想要的任何类型的值传递Promise.resolve无论是否promise。该方法本身返回带有已解析值的Promise (fulfilled)。如果您传递常规函数它将是具有常规值的已解决promise。如果你通过了 promise它将是一个已经 resolved 的且带有传的值的 promise。
上述情况我们传了数字 5因此返回一个 resolved 状态的 promiseresolve 值为5
105. 输出什么
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: ReferenceErrorD: SyntaxError
答案 答案B
对象通过引用传递。当我们检查对象的严格相等性时我们正在比较它们的引用。
我们将“person2”的默认值设置为“person”对象并将“person”对象作为“person1”的值传递。
这意味着两个值都引用内存中的同一位置因此它们是相等的。
运行“else”语句中的代码块并记录They are the same!。 106. 输出什么
const colorConfig {red: true,blue: false,green: true,black: true,yellow: false,
}const colors [pink, red, blue]console.log(colorConfig.colors[1])A: trueB: falseC: undefinedD: TypeError
答案 答案D
在 JavaScript 中我们有两种访问对象属性的方法括号表示法或点表示法。在此示例中我们使用点表示法colorConfig.colors代替括号表示法colorConfig [“colors”]。
使用点表示法JavaScript 会尝试使用该确切名称在对象上查找属性。在此示例中JavaScript 尝试在 colorConfig 对象上找到名为 colors 的属性。没有名为“colors”的属性因此返回“undefined”。 然后我们尝试使用[1]访问第一个元素的值。我们无法对未定义的值执行此操作因此会抛出Cannot read property 1 of undefined。
JavaScript 解释或取消装箱语句。当我们使用方括号表示法时它会看到第一个左方括号[并一直进行下去直到找到右方括号]。只有这样它才会评估该语句。如果我们使用了 colorConfig [colors [1]]它将返回 colorConfig 对象上 red 属性的值。 107. 输出什么
console.log(❤️ ❤️)A: trueB: false
答案 答案A
在内部表情符号是 unicode。heat 表情符号的 unicode 是“U 2764 U FE0F”。对于相同的表情符号它们总是相同的因此我们将两个相等的字符串相互比较这将返回 true。 108. 哪些方法修改了原数组
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 themB: map reduce slice spliceC: map slice spliceD: splice
答案 答案D
使用splice方法我们通过删除替换或添加元素来修改原始数组。在这种情况下我们从索引 1 中删除了 2 个元素我们删除了和同时添加了✨emoji 表情。
mapfilter和slice返回一个新数组find返回一个元素而reduce返回一个减小的值。 109. 输出什么
const food [, , , ]
const info { favoriteFood: food[0] }info.favoriteFood console.log(food)A: [, , , ]B: [, , , ]C: [, , , , ]D: ReferenceError
答案 答案A
我们将info对象上的favoriteFood属性的值设置为披萨表情符号“”的字符串。字符串是原始数据类型。在 JavaScript 中原始数据类型通过值起作用
在这种情况下我们将info对象上的favoriteFood属性的值设置为等于food数组中的第一个元素的值字符串为披萨表情符号。字符串是原始数据类型并且通过值进行交互我们更改info对象上favoriteFood属性的值。food 数组没有改变因为 favoriteFood 的值只是该数组中第一个元素的值的复制并且与该元素上的元素没有相同的内存引用食物[0]。当我们记录食物时它仍然是原始数组[]。 110. 这个函数干了什么
JSON.parse()A: Parses JSON to a JavaScript valueB: Parses a JavaScript object to JSONC: Parses any JavaScript value to JSOND: Parses JSON to a JavaScript object only
答案 答案A
使用JSON.parse()方法我们可以将 JSON 字符串解析为 JavaScript 值。
// 将数字字符串化为有效的 JSON然后将 JSON 字符串解析为 JavaScript 值
const jsonNumber JSON.stringify(4) // 4
JSON.parse(jsonNumber) // 4// 将数组值字符串化为有效的 JSON然后将 JSON 字符串解析为 JavaScript 值
const jsonArray JSON.stringify([1, 2, 3]) // [1, 2, 3]
JSON.parse(jsonArray) // [1, 2, 3]// 将对象字符串化为有效的 JSON然后将 JSON 字符串解析为 JavaScript 值
const jsonArray JSON.stringify({ name: Lydia }) // {name:Lydia}
JSON.parse(jsonArray) // { name: Lydia }111. 输出什么
let name Lydiafunction getName() {console.log(name)let name Sarah
}getName()A: LydiaB: SarahC: undefinedD: ReferenceError
答案 答案D
每个函数都有其自己的执行上下文。getName函数首先在其自身的上下文范围内查找以查看其是否包含我们尝试访问的变量name。上述情况getName函数包含其自己的name变量我们用let关键字和Sarah的值声明变量name。
带有let关键字和const的变量被提升但是与var不同它不会被*** 初始化***。在我们声明初始化它们之前无法访问它们。这称为“暂时性死区”。当我们尝试在声明变量之前访问变量时JavaScript 会抛出ReferenceError: Cannot access name before initialization。
如果我们不在getName函数中声明name变量则 javascript 引擎会查看原型链。会找到其外部作用域有一个名为name的变量其值为Lydia。在这种情况下它将打印Lydia
let name Lydiafunction getName() {console.log(name)
}getName() // Lydia112. 输出什么
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: a and aB: a and undefinedC: [a, b, c] and aD: a and [a, b, c]
答案 答案C
通过 yield 关键字我们在 Generator 函数里执行yield表达式。通过 yield* 关键字我们可以在一个Generator 函数里面执行yield表达式另一个 Generator 函数或可遍历的对象 (如数组).
在函数 generatorOne 中我们通过 yield 关键字 yield 了一个完整的数组 [a, b, c]。函数one通过next方法返回的对象的value 属性的值 (one.next().value) 等价于数组 [a, b, c].
console.log(one.next().value) // [a, b, c]
console.log(one.next().value) // undefined在函数 generatorTwo 中我们使用 yield* 关键字。就相当于函数two第一个yield的值等价于在迭代器中第一个 yield 的值。数组[a, b, c]就是这个迭代器。第一个 yield 的值就是 a所以我们第一次调用 two.next().value时就返回a。
console.log(two.next().value) // a
console.log(two.next().value) // b
console.log(two.next().value) // c
console.log(two.next().value) // undefined113. 输出什么
console.log(${(x x)(I love)} to program)A: I love to programB: undefined to programC: ${(x x)(I love) to programD: TypeError
答案 答案A
带有模板字面量的表达式首先被执行。相当于字符串会包含表达式这个立即执行函数 (x x)(I love) 返回的值。我们向箭头函数 x x 传递 I love 作为参数。x 等价于返回的 I love。这就是结果 I love to program。 114. 将会发生什么
let config {alert: setInterval(() {console.log(Alert!)}, 1000)
}config nullA: setInterval 的回调不会被调用B: setInterval 的回调被调用一次C: setInterval 的回调仍然会被每秒钟调用D: 我们从没调用过 config.alert(), config 为 null
答案 答案C
一般情况下当我们将对象赋值为 null那些对象会被进行 垃圾回收garbage collected 因为已经没有对这些对象的引用了。然而setInterval的参数是一个箭头函数所以上下文绑定到对象 config 了回调函数仍然保留着对 config的引用。只要存在引用对象就不会被垃圾回收。因为没有被垃圾回收setInterval 的回调每 1000ms (1s) 会被调用一次。 115. 哪一个方法会返回 Hello world!
const myMap new Map()
const myFunc () greetingmyMap.set(myFunc, Hello world!)//1
myMap.get(greeting)
//2
myMap.get(myFunc)
//3
myMap.get(() greeting)A: 1B: 2C: 2 and 3D: All of them
答案 答案B
当通过 set 方法添加一个键值对一个传递给 set方法的参数将会是键名第二个参数将会是值。在这个 case 里键名为 函数 () greeting值为Hello world。 myMap 现在就是 { () greeting Hello world! }。
1 是错的因为键名不是 greeting 而是 () greeting。 3 是错的因为我们给get 方法传递了一个新的函数。对象受 引用 影响。函数也是对象因此两个函数严格上并不等价尽管他们相同他们有两个不同的内存引用地址。 116. 输出什么
const person {name: Lydia,age: 21
}const changeAge (x { ...person }) x.age 1
const changeAgeAndName (x { ...person }) {x.age 1x.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
函数 changeAge 和函数 changeAgeAndName 有着不同的参数定义一个 新 生成的对象 { ...person }。这个对象有着所有 person 对象 中 k/v 值的副本。
首项我们调用 changeAge 函数并传递 person 对象作为它的参数。这个函数对 age 属性进行加一操作。person 现在是 { name: Lydia, age: 22 }。
然后我们调用函数 changeAgeAndName然而我们没有传递参数。取而代之x 的值等价 new 生成的对象{ ...person }。因为它是一个新生成的对象它并不会对对象 person 造成任何副作用。person 仍然等价于 { name: Lydia, age: 22 }。 117. 下面那个选项将会返回 6?
function sumValues(x, y, z) {return x y z;
}A: sumValues([...1, 2, 3])B: sumValues([...[1, 2, 3]])C: sumValues(...[1, 2, 3])D: sumValues([1, 2, 3])
答案 答案C
通过展开操作符 ...我们可以 暂开 单个可迭代的元素。函数 sumValues function 接收三个参数x, y 和 z。...[1, 2, 3] 的执行结果为 1, 2, 3将会传递给函数 sumValues。 118. 输出什么
let num 1;
const list [, , , ];console.log(list[(num 1)]);A: B: C: SyntaxErrorD: ReferenceError
答案 答案B
通过 操作符我们对值 num 进行加 1 操作。num 有初始值 1因此 1 1 的执行结果为 2。数组 list 的第二项为 console.log(list[2]) 输出 . 119. 输出什么
const person {firstName: Lydia,lastName: Hallie,pet: {name: Mara,breed: Dutch Tulip Hound},getFullName() {return ${this.firstName} ${this.lastName};}
};console.log(person.pet?.name);
console.log(person.pet?.family?.name);
console.log(person.getFullName?.());
console.log(member.getLastName?.());A: undefined undefined undefined undefinedB: Mara undefined Lydia Hallie ReferenceErrorC: Mara null Lydia Hallie nullD: null ReferenceError null ReferenceError
答案 答案B
通过 ES10 或 TS3.7可选链操作符 ?.我们不再需要显式检测更深层的嵌套值是否有效。如果我们尝试获取 undefined 或 null 的值 (nullish)表达将会短路并返回 undefined.
person.pet?.nameperson 有一个名为 pet 的属性person.pet 不是 nullish。它有个名为 name 的属性并返回字符串 Mara。 person.pet?.family?.nameperson 有一个名为 pet 的属性person.pet 不是 nullish. pet 并没有 一个名为 family 的属性person.pet.family 是 nullish。表达式返回 undefined。 person.getFullName?.()person 有一个名为 getFullName 的属性person.getFullName() 不是 nullish 并可以被调用返回字符串 Lydia Hallie。 member.getLastName?.(): 变量member 不存在因此会抛出错误ReferenceError。 120. 输出什么
const groceries [banana, apple, peanuts];if (groceries.indexOf(banana)) {console.log(We have to buy bananas!);
} else {console.log(We dont have to buy bananas!);
}A: We have to buy bananas!B: We don’t have to buy bananasC: undefinedD: 1
答案 答案B
我们传递了一个状态 groceries.indexOf(banana) 给 if 条件语句。groceries.indexOf(banana) 返回 0一个 falsy 的值。因为 if 条件语句的状态为 falsyelse 块区内的代码执行并且 We dont have to buy bananas! 被输出。 121. 输出什么
const config {languages: [],set language(lang) {return this.languages.push(lang);}
};console.log(config.language);A: function language(lang) { this.languages.push(lang }B: 0C: []D: undefined
答案 答案D
方法 language 是一个 setter。Setters 并不保存一个实际值它们的使命在于 修改 属性。当调用方法 setter返回 undefined。 122. 输出什么
const name Lydia Hallie;console.log(!typeof name object);
console.log(!typeof name string);A: false trueB: true falseC: false falseD: true true
答案 答案C
typeof name 返回 string。字符串 string 是一个 truthy 的值因此 !typeof name 返回一个布尔值 false。false object 和 false string 都返回 false。
如果我们想检测一个值的类型我们应该用 ! 而不是 !typeof 123. 输出什么
const add x y z {console.log(x, y, z);return x y z;
};add(4)(5)(6);A: 4 5 6B: 6 5 4C: 4 function functionD: undefined undefined 6
答案 答案A
函数 add 是一个返回 返回箭头函数的箭头函数 的箭头函数still with me?。第一个函数接收一个值为 4 的参数 x。我们调用第二个函数它接收一个值为 5 的参数 y。然后我们调用第三个函数它接收一个值为 6 的参数 z。当我们尝试在最后一个箭头函数中获取 x, y 和 z 的值JS 引擎根据作用域链去找 x 和 y 的值。得到 4 5 6. 124. 输出什么
async function* range(start, end) {for (let i start; i end; i) {yield Promise.resolve(i);}
}(async () {const gen range(1, 3);for await (const item of gen) {console.log(item);}
})();A: Promise {1} Promise {2} Promise {3}B: Promise {pending} Promise {pending} Promise {pending}C: 1 2 3D: undefined undefined undefined
答案 答案C
我们给 函数 range 传递Promise{1}, Promise{2}, Promise{3}Generator 函数 range 返回一个全是 async object promise 数组。我们将 async object 赋值给变量 gen之后我们使用for await ... of 进行循环遍历。我们将返回的 Promise 实例赋值给 item第一个返回 Promise{1}第二个返回 Promise{2}之后是 Promise{3}。因为我们正 awaiting item 的值resolved 状态的 promisepromise 数组的 resolved 值 以此为123. 125. 输出什么
const myFunc ({ x, y, z }) {console.log(x, y, z);
};myFunc(1, 2, 3);A: 1 2 3B: {1: 1} {2: 2} {3: 3}C: { 1: undefined } undefined undefinedD: undefined undefined undefined
答案 答案D
myFunc 期望接收一个包含 x, y 和 z 属性的对象作为它的参数。因为我们仅仅传递三个单独的数字值 (1, 2, 3) 而不是一个含有 x, y 和 z 属性的对象 ({x: 1, y: 2, z: 3})x, y 和 z 有着各自的默认值 undefined. 126. 输出什么
function getFine(speed, amount) {const formattedSpeed new Intl.NumberFormat(en-US,{ style: unit, unit: mile-per-hour }).format(speed)const formattedAmount new Intl.NumberFormat(en-US,{ style: currency, currency: USD }).format(amount)return The driver drove ${formattedSpeed} and has to pay ${formattedAmount}
}console.log(getFine(130, 300))A: The driver drove 130 and has to pay 300B: The driver drove 130 mph and has to pay $300.00C: The driver drove undefined and has to pay undefinedD: The driver drove 130.00 and has to pay 300.00
答案 答案B
通过方法 Intl.NumberFormat我们可以格式化任意区域的数字值。我们对数字值 130 进行 mile-per-hour 作为 unit 的 en-US 区域 格式化结果为 130 mph。对数字值 300 进行 USD 作为 currency 的 en-US 区域格式化结果为 $300.00. 127. 输出什么
const spookyItems [, , ];
({ item: spookyItems[3] } { item: });console.log(spookyItems);A: [, , ]B: [, , , ]C: [, , , { item: }]D: [, , , [object Object]]
答案 答案B
通过解构对象们我们可以从右手边的对象中拆出值并且将拆出的值分配给左手边对象同名的属性。在这种情况下我们将值 “” 分配给 spookyItems[3]。相当于我们正在篡改数组 spookyItems我们给它添加了值 “”。当输出 spookyItems 时结果为 [, , , ]。 128. 输出什么
const name Lydia Hallie;
const age 21;console.log(Number.isNaN(name));
console.log(Number.isNaN(age));console.log(isNaN(name));
console.log(isNaN(age));A: true false true falseB: true false false falseC: false false true falseD: false true false true
答案 答案C
通过方法 Number.isNaN你可以检测你传递的值是否为 数字值 并且是否等价于 NaN。name 不是一个数字值因此 Number.isNaN(name) 返回 false。age 是一个数字值但它不等价于 NaN因此 Number.isNaN(age) 返回 false.
通过方法 isNaN你可以检测你传递的值是否一个 number。name 不是一个 number因此 isNaN(name) 返回 true. age 是一个 number 因此 isNaN(age) 返回 false. 129. 输出什么
const randomValue 21;function getInfo() {console.log(typeof randomValue);const randomValue Lydia Hallie;
}getInfo();A: numberB: stringC: undefinedD: ReferenceError
答案 答案D
通过 const 关键字声明的变量在被初始化之前不可被引用这被称之为 暂时性死区。在函数 getInfo 中变量 randomValue 声明在getInfo 的作用域的此法环境中。在想要对 typeof randomValue 进行 log 之前变量 randomValue 仍未被初始化错误ReferenceError 被抛出JS 引擎并不会根据作用域链网上寻找该变量因为我们已经在 getInfo 函数中声明了 randomValue 变量。 130. 输出什么
const myPromise Promise.resolve(Woah some cool data);(async () {try {console.log(await myPromise);} catch {throw new Error(Oops didnt work);} finally {console.log(Oh finally!);}
})();A: Woah some cool dataB: Oh finally!C: Woah some cool data Oh finally!D: Oops didnt work Oh finally!
答案 答案C
在 try 块区我们打印 myPromise 变量的 awaited 值Woah some cool data。因为try 块区没有错误抛出catch 块区的代码并不执行。finally 块区的代码 总是 执行Oh finally! 被输出。 131. 输出什么
const emojis [, [✨, ✨, [, ]]];console.log(emojis.flat(1));A: [, [✨, ✨, [, ]]]B: [, ✨, ✨, [, ]]C: [, [✨, ✨, , ]]D: [, ✨, ✨, , ]
答案 答案B
通过方法 flat我们可以创建一个新的已被扁平化的数组。被扁平化的深度取决于我们传递的值。在这个 case 里我们传递了值 1 (并不必要这是默认值)相当于只有第一层的数组才会被连接。即这个 case 里的 [] and [✨, ✨, [, ]]。连接这两个数组得到结果 [, ✨, ✨, [, ]]. 132. 输出什么
class Counter {constructor() {this.count 0;}increment() {this.count;}
}const counterOne new Counter();
counterOne.increment();
counterOne.increment();const counterTwo counterOne;
counterTwo.increment();console.log(counterOne.count);A: 0B: 1C: 2D: 3
答案 答案D
counterOne 是类 Counter 的一个实例。类 Counter 包含一个count 属性在它的构造函数里和一个 increment 方法。首先我们通过 counterOne.increment() 调用方法 increment 两次。现在counterOne.count 为 2. 然后我们创建一个新的变量 counterTwo 并将 counterOne 的引用地址赋值给它。因为对象受引用地址的影响我们刚刚创建了一个新的对象其引用地址和 counterOne 的等价。因此它们指向同一块内存地址任何对其的副作用都会影响 counterTwo。现在 counterTwo.count 为 2。
我们调用 counterTwo.increment() 将 count 的值设为 3。然后我们打印 counterOne 里的 count结果为 3。 133. 输出什么
const myPromise Promise.resolve(Promise.resolve(Promise!));function funcOne() {myPromise.then(res res).then(res console.log(res));setTimeout(() console.log(Timeout!), 0);console.log(Last line!);
}async function funcTwo() {const res await myPromise;console.log(await res);setTimeout(() console.log(Timeout!), 0);console.log(Last line!);
}funcOne();
funcTwo();A: Promise! Last line! Promise! Last line! Last line! Promise!B: Last line! Timeout! Promise! Last line! Timeout! Promise!C: Promise! Last line! Last line! Promise! Timeout! Timeout!D: Last line! Promise! Promise! Last line! Timeout! Timeout!
答案 答案D
首先我们调用 funcOne。在函数 funcOne 的第一行我们调用myPromise promise 异步操作。当 JS 引擎在忙于执行 promise它继续执行函数 funcOne。下一行 异步操作 setTimeout其回调函数被 Web API 调用。 (详情请参考我关于 event loop 的文章.)
promise 和 timeout 都是异步操作函数继续执行当 JS 引擎忙于执行 promise 和 处理 setTimeout 的回调。相当于 Last line! 首先被输出因为它不是异步操作。执行完 funcOne 的最后一行promise 状态转变为 resolvedPromise! 被打印。然而因为我们调用了 funcTwo()调用栈不为空setTimeout 的回调仍不能入栈。
我们现在处于 funcTwo先 awaiting myPromise。通过 await 关键字我们暂停了函数的执行直到 promise 状态变为 resolved (或 rejected)。然后我们输出 res 的 awaited 值因为 promise 本身返回一个 promise。接着输出 Promise!。
下一行就是 异步操作 setTimeout其回调函数被 Web API 调用。
我们执行到函数 funcTwo 的最后一行输出 Last line!。现在因为 funcTwo 出栈调用栈为空。在事件队列中等待的回调函数() console.log(Timeout!) from funcOne, and () console.log(Timeout!) from funcTwo以此入栈。第一个回调输出 Timeout!并出栈。然后第二个回调输出 Timeout!并出栈。得到结果 Last line! Promise! Promise! Last line! Timeout! Timeout! 134. 我们怎样才能在 index.js 中调用 sum.js? 中的 sum
// sum.js
export default function sum(x) {return x x;
}// index.js
import * as sum from ./sum;A: sum(4)B: sum.sum(4)C: sum.default(4)D: 默认导出不用 * 来导入只能具名导出
答案 答案C
使用符号 *我们引入文件中的所有值包括默认和具名。如果我们有以下文件
// info.js
export const name Lydia;
export const age 21;
export default I love JavaScript;// index.js
import * as info from ./info;
console.log(info);将会输出以下内容
{default: I love JavaScript,name: Lydia,age: 21
}以 sum 为例相当于以下形式引入值 sum
{ default: function sum(x) { return x x } }我们可以通过调用 sum.default 来调用该函数 135. 输出什么
const handler {set: () console.log(Added a new property!),get: () console.log(Accessed a property!)
};const person new Proxy({}, handler);person.name Lydia;
person.name;A: Added a new property!B: Accessed a property!C: Added a new property! Accessed a property!D: 没有任何输出
答案 答案C
使用 Proxy 对象我们可以给一个对象添加自定义行为。在这个 case我们传递一个包含以下属性的对象 handler : set and get。每当我们 设置 属性值时 set 被调用每当我们 获取 时 get 被调用。
第一个参数是一个空对象 {}作为 person 的值。对于这个对象自定义行为被定义在对象 handler。如果我们向对象 person 添加属性set 将被调用。如果我们获取 person 的属性get 将被调用。
首先我们向 proxy 对象 (person.name Lydia) 添加一个属性 name。set 被调用并输出 Added a new property!。
然后我们获取 proxy 对象的一个属性对象 handler 的属性 get 被调用。输出 Accessed a property!。 136. 以下哪一项会对对象 person 有副作用
const person { name: Lydia Hallie };Object.seal(person);A: person.name Evan BaconB: person.age 21C: delete person.nameD: Object.assign(person, { age: 21 })
答案 答案A
使用 Object.seal 我们可以防止新属性 被添加或者存在属性 被移除.
然而你仍然可以对存在属性进行更改。 137. 以下哪一项会对对象 person 有副作用
const person {name: Lydia Hallie,address: {street: 100 Main St}
};Object.freeze(person);A: person.name Evan BaconB: delete person.addressC: person.address.street 101 Main StD: person.pet { name: Mara }
答案 答案C
使用方法 Object.freeze 对一个对象进行 冻结。不能对属性进行添加修改删除。
然而它仅 对对象进行 浅 冻结意味着只有 对象中的 直接 属性被冻结。如果属性是另一个 object像案例中的 addressaddress 中的属性没有被冻结仍然可以被修改。 138. 输出什么
const add x x x;function myFunc(num 2, value add(num)) {console.log(num, value);
}myFunc();
myFunc(3);A: 2 4 and 3 6B: 2 NaN and 3 NaNC: 2 Error and 3 6D: 2 4 and 3 Error
答案 答案A
首先我们不传递任何参数调用 myFunc()。因为我们没有传递参数num 和 value 获取它们各自的默认值num 为 2而 value 为函数 add 的返回值。对于函数 add我们传递值为 2 的 num 作为参数。函数 add 返回 4 作为 value 的值。
然后我们调用 myFunc(3) 并传递值 3 参数 num 的值。我们没有给 value 传递值。因为我们没有给参数 value 传递值它获取默认值函数 add 的返回值。对于函数 add我们传递值为 3 的 num给它。函数 add 返回 6 作为 value 的值。 139. 输出什么
class Counter {#number 10increment() {this.#number}getNum() {return this.#number}
}const counter new Counter()
counter.increment()console.log(counter.#number)A: 10B: 11C: undefinedD: SyntaxError
答案 答案D
在 ES2020 中通过 # 我们可以给 class 添加私有变量。在 class 的外部我们无法获取该值。当我们尝试输出 counter.#number语法错误被抛出我们无法在 class Counter 外部获取它 140. 选择哪一个
const teams [{ name: Team 1, members: [Paul, Lisa] },{ name: Team 2, members: [Laura, Tim] }
];function* getMembers(members) {for (let i 0; i members.length; i) {yield members[i];}
}function* getTeams(teams) {for (let i 0; i teams.length; i) {// ✨ SOMETHING IS MISSING HERE ✨}
}const obj getTeams(teams);
obj.next(); // { value: Paul, done: false }
obj.next(); // { value: Lisa, done: false }A: yield getMembers(teams[i].members)B: yield* getMembers(teams[i].members)C: return getMembers(teams[i].members)D: return yield getMembers(teams[i].members)
答案 答案B
为了遍历 teams 数组中对象的属性 members 中的每一项我们需要将 teams[i].members 传递给 Generator 函数 getMembers。Generator 函数返回一个 generator 对象。为了遍历这个 generator 对象中的每一项我们需要使用 yield*.
如果我们没有写 yieldreturn yield 或者 return整个 Generator 函数不会第一时间 return 当我们调用 next 方法。 141. 输出什么
const person {name: Lydia Hallie,hobbies: [coding]
};function addHobby(hobby, hobbies person.hobbies) {hobbies.push(hobby);return hobbies;
}addHobby(running, []);
addHobby(dancing);
addHobby(baking, person.hobbies);console.log(person.hobbies);A: [coding]B: [coding, dancing]C: [coding, dancing, baking]D: [coding, running, dancing, baking]
答案 答案C
函数 addHobby 接受两个参数hobby 和有着对象 person 中数组 hobbies 默认值的 hobbies。
首相我们调用函数 addHobby并给 hobby 传递 running 以及给 hobbies 传递一个空数组。因为我们给 hobbies 传递了空数组running 被添加到这个空数组。
然后我们调用函数 addHobby并给 hobby 传递 dancing。我们不向 hobbies 传递值因此它获取其默认值 —— 对象 person 的 属性 hobbies。我们向数组 person.hobbies push dancing。
最后我们调用函数 addHobby并向 hobby 传递 值 baking并且向 hobbies 传递 person.hobbies。我们向数组 person.hobbies push dancing。
pushing dancing 和 baking 之后person.hobbies 的值为 [coding, dancing, baking] 142. 输出什么
class Bird {constructor() {console.log(Im a bird. );}
}class Flamingo extends Bird {constructor() {console.log(Im pink. );super();}
}const pet new Flamingo();A: Im pink. B: Im pink. Im a bird. C: Im a bird. Im pink. D: Nothing, we didn’t call any method
答案 答案B
我们创建了类 Flamingo 的实例 pet。当我们实例化这个实例Flamingo 中的 constructor 被调用。首相输出 Im pink. 之后我们调用super()。super() 调用父类的构造函数Bird。Bird 的构造函数被调用并输出 Im a bird. 。 143. 哪一个选项会导致报错
const emojis [, , , ⭐];/* 1 */ emojis.push();
/* 2 */ emojis.splice(0, 2);
/* 3 */ emojis [...emojis, ];
/* 4 */ emojis.length 0;A: 1B: 1 and 2C: 3 and 4D: 3
答案 答案D
const 关键字意味着我们不能 重定义 变量中的值它 仅可读。然而值本身不可修改。数组 emojis 中的值可被修改如 push 新的值拼接又或者将数组的长度设置为 0。 144. 我们需要向对象 person 添加什么以致执行 [...person] 时获得形如 [Lydia Hallie, 21] 的输出
const person {name: Lydia Hallie,age: 21
}[...person] // [Lydia Hallie, 21]A: 不需要对象默认就是可迭代的B: *[Symbol.iterator]() { for (let x in this) yield* this[x] }C: *[Symbol.iterator]() { yield* Object.values(this) }D: *[Symbol.iterator]() { for (let x in this) yield this }
答案 答案C
对象默认并不是可迭代的。如果迭代规则被定义则一个对象是可迭代的An iterable is an iterable if the iterator protocol is present。我们可以通过添加迭代器 symbol [Symbol.iterator] 来定义迭代规则其返回一个 generator 对象比如说构建一个 generator 函数 *[Symbol.iterator]() {}。如果我们想要返回数组 [Lydia Hallie, 21]: yield* Object.values(this)这个 generator 函数一定要 yield 对象 person 的Object.values。 145. 输出什么
let count 0;
const nums [0, 1, 2, 3];nums.forEach(num {if (num) count 1
})console.log(count)A: 1B: 2C: 3D: 4
答案 答案C
在 forEach 循环内部的 if 会判断 num 的值是 truthy 或者是 falsy。因为 nums 数组的第一个数字是 0一个 falsy 值if 语句代码块不会被执行。count 仅仅在 nums 数组的其他 3 个数字 123 时加 1。因为 count 执行了 3 次加 1 运算所以 count 的值为 3。 146. 输出是什么
function getFruit(fruits) {console.log(fruits?.[1]?.[1])
}getFruit([[, ], []])
getFruit()
getFruit([[], [, ]])A: null, undefined, B: [], null, C: [], [], D: undefined, undefined,
答案 答案D
? 允许我们去选择性地访问对象内部更深层的嵌套属性。我们尝试打印 fruits 数组索引值为 1 的子数组内部的索引值为 1 的元素。如果在 fruits 数组索引值 为 1 的位置不存在元素会直接返回 undefined。如果 fruits 数组在索引值为 1 的位置存在元素但是子数组在索引值为 1 的位置不存在元素也会返回 undefined。
首先我们尝试打印 [[, ], []] 的子数组 [] 的第 2 个元素。这个子数组只包含一个元素也就意味着在索引值为 1 的位置不存在元素所以返回的是 undefined。
其次我们在没有传入任何参数调用了 getFruits 函数也就意味着形参 fruits 的默认值为undefined。因为我们选择性地链接了 fruits 在索引值为 1 的元素因为在索引值为 1 的位置不存在元素因此返回的是 undefined。
最后我们尝试打印 [], [, ] 的子数组 [, ] 的第 2 个元素。子数组索引值为 1的位置为 因此它被打印出了。 147. 输出什么
class Calc {constructor() {this.count 0 }increase() {this.count }
}const calc new Calc()
new Calc().increase()console.log(calc.count)A: 0B: 1C: undefinedD: ReferenceError
答案 答案A
我们设置 calc 变量为 Calc 类的一个新实例。然后我们初始化一个 Calc 的新实例而且调用了这个实例的 increase 方法。因为 count 属性是在 Calc class 的 constructor 内部的所以 count 属性不会在 Calc 的原型链上共享出去。这就意味着 calc 实例的 count 值不会被更新count 仍然是 0。 148. 输出什么
const user {email: email.com,password: 12345
}const updateUser ({ email, password }) {if (email) {Object.assign(user, { email })}if (password) {user.password password}return user
}const updatedUser updateUser({ email: newemail.com })console.log(updatedUser user)A: falseB: trueC: TypeErrorD: ReferenceError
答案 答案B
updateUser 函数更新 user 的 email 和 password 属性的值如果它们的值传入函数函数返回的就是 user 对象。updateUser 函数的返回值是 user 对象意味着 updatedUser 的值与 user 指向的是同一个 user 对象。updatedUser user 为 true. 149. 输出什么
const fruit [, , ]fruit.slice(0, 1)
fruit.splice(0, 1)
fruit.unshift()console.log(fruit)A: [, , ]B: [, ]C: [, , ]D: [, , , ]
答案 答案C
首先我们在 fruit 数组上调用 slice 方法。slice 方法不会修改原始数组但是会返回从数组切片下来的值香蕉 emoji。 其次我们在 fruit 数组上调用 splice 方法。splice 方法会修改原始数组也就意味着 fruit 数组此时为 [, ]。 最后我们在 fruit 数组上调用 unshift 方法通过添加一个值的方式改变了原始数组添加的是’’它成为了数组的第一个元素。现在 fruit 数组的组成为 [, , ]。 150. 输出什么
const animals {};
let dog { emoji: }
let cat { emoji: }animals[dog] { ...dog, name: Mara }
animals[cat] { ...cat, name: Sara }console.log(animals[dog])A: { emoji: , name: Mara }B: { emoji: , name: Sara }C: undefinedD: ReferenceError
答案 答案B
对象的键会被转换为字符串。
因为 dog 的值是一个对象animals[dog] 实际上意味着我们创建了一个叫做 object Object 的属性来代表新的对象。animals[object Object] 现在等于 { emoji: , name: Mara}。
cat 也是一个对象animals[cat] 实际上意味着我们在用新的 cat 的属性覆盖 animals[object Object] 的值。
打印 animals[dog]实际上是animals[object Object]这是因为转化dog对象为一个字符串结果 object Object所以返回 { emoji: , name: Sara }。 151. 输出什么
const user {email: myemail.com,updateEmail: email {this.email email}
}user.updateEmail(newemail.com)
console.log(user.email)A: myemail.comB: newemail.comC: undefinedD: ReferenceError
答案 答案A
updateEmail 函数是一个箭头函数它没有和 user 对象绑定。这就意味着 this 关键字不会引用到 user 对象但是会引用到全局对象。user 对象内部的 email 的值不会更新。当打印 user.email 的时候原始值 myemail.com 被返回。 152. 输出什么
const promise1 Promise.resolve(First)
const promise2 Promise.resolve(Second)
const promise3 Promise.reject(Third)
const promise4 Promise.resolve(Fourth)const runPromises async () {const res1 await Promise.all([promise1, promise2])const res2 await Promise.all([promise3, promise4])return [res1, res2]
}runPromises().then(res console.log(res)).catch(err console.log(err))A: [[First, Second], [Fourth]]B: [[First, Second], [Third, Fourth]]C: [[First, Second]]D: Third
答案 答案D
Promise.all 方法可以并行式运行 promise。如果其中一个 promise 失败了Promise.all 方法会带上被 reject 的 promise 的值_rejects_。在这个例子中promise3 带着 Third 值 reject。我们在调用 runPromises 时在 runPromises 函数内部的 catch 方法去捕获任意 error 从而捕获到被 reject 的值。因为 promise3 带着 Third 被 reject所以只有 Third 打印。 153. 哪个作为method的值可以打印{ name: Lydia, age: 22 }?
const keys [name, age]
const values [Lydia, 22]const method /* ?? */
Object[method](keys.map((_, i) {return [keys[i], values[i]]
})) // { name: Lydia, age: 22 }A: entriesB: valuesC: fromEntriesD: forEach
答案 答案C
fromEntries 方法可以将二维数组转换为对象。在每个子数组的第一个元素是 key在每个子数组的第二个元素是 value。在这个例子中我们映射了 keys 数组它返回了一个数组数组的第一个元素为 keys 数组当前索引的值第二个元素为 values 数组当前索引的值。
这样就创建了一个包含正确 keys 和 values 的子数组的数组因此结果为{ name: Lydia, age: 22 }。 154. 输出什么
const createMember ({ email, address {}}) {const validEmail /.\.\../.test(email)if (!validEmail) throw new Error(Valid email pls)return {email,address: address ? address : null}
}const member createMember({ email: myemail.com })
console.log(member)A: { email: myemail.com, address: null }B: { email: myemail.com }C: { email: myemail.com, address: {} }D: { email: myemail.com, address: undefined }
答案 答案C
address 的默认值是一个空对象 {}。当我们设置 member 变量为 createMember 函数返回的对象我们没有为 address 参数传值意味着 address 的值为默认的空对象 {}。一个空对象是一个 truthy 值意味着 address ? address : null 条件会返回 true。address 的值为空对象 {}。 155. 输出什么
let randomValue { name: Lydia }
randomValue 23if (!typeof randomValue string) {console.log(Its not a string!)
} else {console.log(Yay its a string!)
}A: Its not a string!B: Yay its a string!C: TypeErrorD: undefined
答案 答案B
if 语句的条件判断 !typeof randomValue 的值是否等于 string。! 操作符将这个值转化为一个布尔值。如果值是 truthy 的话返回值会是 false如果值是 falsy返回值会是 true。在这里typeof randomValue 的返回值是一个 truthy 值 number意味着 !typeof randomValue 的值是一个布尔值 false。
!typeof randomValue string 总是返回 false因为我们实际上是在执行 false string。因为条件返回的是 false所以 else 语句中的代码块会被运行因此打印 Yay its a string!。