今天我们将继续学习我们钟爱的 JavaScript 语言,在这一版中,我们将通过回答一些 JavaScript 小挑战来测试我们的技能。
尽管我会在每个问题的结尾给出答案,但请先尝试自己弄清楚,然后再根据我的答案验证你的答案。
问题 1:数组排序比较
JavaScript常见问题有哪些?考虑以下数组和条件,你认为结果是什么?
const arr1 = ['a', 'b', 'c']
const arr2 = ['c', 'b', 'a']
console.log(
arr1.sort() === arr1,
arr2 === arr2.sort(),
arr1.sort() === arr2.sort()
)
回答
true true false
现在我们知道了结果,让我们解释一下原因。对于前 2 个输出,解释相当简单,该sort()
方法对原始数组进行排序并返回对同一对象arr1.sort()
的引用,因此实际上是对同一对象的引用arr1
。
JavaScript常见问题解答 - 对于第三个输出,arr1.sort() === arr2.sort()
,即使每个数组上的元素都相同,===
运算符不会测试数组的元素,而是测试每个对象的引用,在这种情况下是不同的,因此返回false
。
如果你想了解更多关于数组比较的信息,请查看我的文章Stranger Things, JavaScript Edition ,并阅读场景 #5:数组相等,我用更多示例解释了一些奇怪的数组比较和解释。
问题 2:对象可变性
对于这个场景,我想模拟一个代表作者的对象,以及关于他的网站的信息。然后我们将使用该方法Object.freeze()
使其无法更改,我们将对其进行测试。你认为会是什么结果?
const author = {
name: 'Juan',
website: {
type: 'blog',
url: 'https://livecodestream.dev',
}
}
Object.freeze(author)
author.website.type = 'test'
console.log(author.website.type)
回答
test
如果你猜对了恭喜你!如果没有,别担心,我也在那里。让我们解释一下发生了什么。
经典JavaScript问题和答案:当我们调用该方法时,Object.freeze()
我们冻结了对象,这意味着该对象不能再被更改;冻结对象可防止向其添加新属性,防止删除或更改现有属性。
但是为什么我们能够改变对象呢?实际上我们没有,这就是诀窍。出于所有目的,变量author
网站是对对象的引用,并且该引用在整个代码中保持不变。我们确实改变了website
对象内部的一个属性,但这并没有改变对对象本身的引用。
如果你想知道如果我们尝试更改author
对象的直接属性会发生什么,有两种可能的答案。让我们从第一个开始:
author.name = 'Laura'
console.log(author.name)
---------
Output
---------
"Juan"
在第一个场景中,即使我们更改了属性并name
没有真正改变,我们没有错误,没有警告,就像那行代码永远不会被执行一样。第二个选项是在严格模式下
"use strict"; author.name = 'Laura'
Uncaught TypeError: Cannot assign to read only property 'name' of object '#<Object>'
at <anonymous>:1:27
在严格模式下,如果我们尝试修改一个冻结的对象,我们会得到一个TypeError
. 比以前好多了。
问题 3:递归
JavaScript常见问题有哪些?给定以下递归函数,当我们以“blog”为参数调用它时,你认为结果是什么?
const recursive = str => {
if (str.length > 1) {
return recursive(str.slice(1))
}
return str
}
console.log(recursive('blog'))
回答
g
JavaScript常见问题解答:对于这个问题没有技巧,只是递归函数的基本用法,它将继续调用自身,直到字符串中只有一个元素str
,从而打印原始字符串的最后一个字符,在这种情况下g
。递归函数很重要,可以以非常有趣的方式解决问题,理解它们很重要。
问题 4:范围
你认为控制台的输出是什么,为什么?
(function(){
const a = b = 3
})()
console.log("a defined? " + (typeof a !== 'undefined'))
console.log("b defined? " + (typeof b !== 'undefined'))
回答
a defined? false
b defined? true
经典JavaScript问题和答案:奇怪的警报!由于a
和b
都在函数的封闭范围内定义,因此你会期望a
和b
实际上都是undefined
。
然而,事实并非如此。这里的问题是常见的误解,它const a = b = 3
是一个简写:const a = 3; const b = 3;
但实际上,它是一个简写
b = 3;
const a = b;
但是如何在封闭函数的范围之外b
定义呢?诀窍是它最终成为一个全局变量(因为前面没有,或)。但仍处于函数的封闭状态。b
let
const
var
a
请注意,在严格模式下,这将生成一个ReferenceError: b is not defined
.
问题 5:更多关于闭包的信息
JavaScript常见问题有哪些?以下片段是一个实际的流行面试问题,问题是,你认为输出会是什么?
for (var i = 0; i < 5; i++) {
setTimeout(function() { console.log(i); }, i * 1000 );
}
回答
5
5
5
5
5
不完全符合你的预期?这样做的原因是循环中执行的每个函数都将在整个循环完成后执行,因此所有函数都将引用存储在 中的最后一个值i
,即5
。
JavaScript常见问题解答 - 通过为每次迭代创建唯一的作用域,将变量的每个唯一值存储在其作用域内,可以使用闭包来防止此问题,如下所示:
for (var i = 0; i < 5; i++) {
(function(x) {
setTimeout(function() { console.log(x); }, x * 1000 );
})(i);
}
ES2015 提供的另一个选项是使用let
代替var
:
for (let i = 0; i < 5; i++) {
setTimeout(function() { console.log(i); }, i * 1000 );
}
经典JavaScript问题和答案概括
我希望你和我一样玩得开心并从中学习,这是一篇特别有趣的文章,以后我可能会做更多这样的事情。
如果你有其他想要回答的问题,或者你是否喜欢这篇文章,请在评论中告诉我。
非常感谢你的阅读!