刷題是我們提升自己科技的好方法。下面的問題很有挑戰性和「指導性」。如果你知道該怎樣回答,那意味著自己的水平很好,但是如果你發現自己答錯了,並且能夠搞清楚為什麼錯,我認為那會更好!
推薦學習:JavaScript影片教學 、 js教學(圖文)
##1 . 數組排序比較
看以下數組,在各種排序運算後都下輸出什麼?const arr1 = ['a', 'b', 'c']; const arr2 = ['b', 'c', 'a']; console.log( arr1.sort() === arr1, arr2.sort() == arr2, arr1.sort() === arr2.sort() );
答案與解析
#答案: true, true, false
這裡有幾個概念在運作。首先,array 的sort 方法會對原始陣列進行排序,並傳回對該陣列的參考。這表示當你呼叫
arr2.sort() 時,
arr2 陣列內的物件將會被排序。
arr1.sort() 和
arr1 指向記憶體中的相同對象,因此第一個相等測試會傳回
true。第二個比較也是如此:
arr2.sort() 和 arr2 指向記憶體中的相同物件。
arr1.sort() 和
arr2.sort() 的排序順序相同;但是,它們指向記憶體中的不同對象。因此,第三個測試的評估結果為
false。
2. set 的物件
把下面的Set 物件轉成一個新的數組,最後輸出什麼?
const mySet = new Set([{ a: 1 }, { a: 1 }]); const result = [...mySet]; console.log(result);
答案與解析
#答案: [{a: 1 }, {a: 1}]
{ a: 1 } === { a: 1 } 的結果為
false 的原因相同。
obj = {a: 1},
new Set([obj,obj]) 將會只有一個元素,因為數組中的兩個元素都引用了記憶體中的相同物件。
3. 深層物件的可變性
#下面的物件代表使用者 Joe 和他的狗 Buttercup。我們用Object.freeze 儲存對象,然後嘗試更改 Buttercup 的 name。最後會輸出什麼?
const user = { name: 'Joe', age: 25, pet: { type: 'dog', name: 'Buttercup', }, }; Object.freeze(user); user.pet.name = 'Daffodil'; console.log(user.pet.name);
答案與解析
#答案:Daffodil
#Daffodil
Object.freeze
user.age 進行修改,但是對 user.pet.name 進行修改卻沒有問題。如果我們覺得需要保護一個對象,避免其「從頭到尾」改變,則可以遞歸地應用 Object.freeze
或使用現有的「深度凍結」函式庫。在下面的程式碼中,有一個
Dog 建構子。我們的 dog 顯然有 speak 這個操作。當我們呼叫 Pogo 的 speak 時,會輸出什麼?
function Dog(name) { this.name = name; this.speak = function() { return 'woof'; }; } const dog = new Dog('Pogo'); Dog.prototype.speak = function() { return 'arf'; }; console.log(dog.speak());
每次创建一个新的 Dog
实例时,我们都会将该实例的 speak
属性设置为返回字符串 woof
的函数。由于每次我们创建一个新的Dog
实例时都要设置该值,因此解释器不会沿着原型链去找 speak
属性。结果就不会使用 Dog.prototype.speak
上的 speak
方法。
5. Promise.all 的解决顺序
在这个问题中,我们有一个 timer
函数,它返回一个 Promise
,该 Promise 在随机时间后解析。我们用 Promise.all
解析一系列的 timer
。最后的输出是什么,是随机的吗?
const timer = a => { return new Promise(res => setTimeout(() => { res(a); }, Math.random() * 100) ); }; const all = Promise.all([timer('first'), timer('second')]).then(data => console.log(data) );
答案和解析
答案: ["first", "second"]
Promise 解决的顺序与 Promise.all 无关。我们能够可靠地依靠它们按照数组参数中提供的相同顺序返回。
6. Reduce 数学
数学时间!输出什么?
const arr = [x => x * 1, x => x * 2, x => x * 3, x => x * 4]; console.log(arr.reduce((agg, el) => agg + el(agg), 1));
答案和解析
答案: 120
使用 Array#reduce
时,聚合器的初始值(在此称为 agg
)在第二个参数中给出。在这种情况下,该值为 1
。然后可以如下迭代函数:
1 + 1 * 1 = 2(下一次迭代中聚合器的值)
2 + 2 * 2 = 6(下一次迭代中聚合器的值)
6 + 6 * 3 = 24(下一次迭代中聚合器的值)
24 + 24 * 4 = 120(最终值)
因此它是 120。
7. 短路通知(Short-Circuit Notification(s))
让我们向用户显示一些通知。以下代码段输出了什么?
const notifications = 1; console.log( `You have ${notifications} notification${notifications !== 1 && 's'}` );
答案和解析
答案:“You have 1 notificationfalse”
不幸的是,我们的短路评估将无法按预期工作: notifications !== 1 && 's'
评估为 false
,这意味着我们实际上将会输出 You have 1 notificationfalse
。如果希望代码段正常工作,则可以考虑条件运算符: ${notifications === 1 ? '' : 's'}
。
8. 展开操作和重命名
查看以下代码中有单个对象的数组。当我们扩展该数组并更改 0 索引对象上的 firstname
属性时会发生什么?
const arr1 = [{ firstName: 'James' }]; const arr2 = [...arr1]; arr2[0].firstName = 'Jonah'; console.log(arr1);
答案和解析
答案: [{ firstName: "Jonah" }]
展开操作符会创建数组的浅表副本,这意味着 arr2
中包含的对象与 arr1
所指向的对象相同。所以在一个数组中修改对象的 firstName
属性,也将会在另一个数组中更改。
9. 数组方法绑定
在以下情况下会输出什么?
const map = ['a', 'b', 'c'].map.bind([1, 2, 3]); map(el => console.log(el));
答案和解析
答案: 1 2 3
当 ['a', 'b', 'c'].map
被调用时,将会调用 this'
值为 '['a','b','c']
的 Array.prototype.map
。但是当用作 引用
时, Array.prototype.map
的引用。
Function.prototype.bind
会将函数的 this
绑定到第一个参数(在本例中为 [1, 2, 3]
),用 this
调用Array.prototype.map
将会导致这些项目被迭代并输出。
10. set 的唯一性和顺序
在下面的代码中,我们用 set
对象和扩展语法创建了一个新数组,最后会输出什么?
const arr = [...new Set([3, 1, 2, 3, 4])]; console.log(arr.length, arr[2]);
答案和解析
答案: 4 2
set
对象会强制里面的元素唯一(集合中已经存在的重复元素将会被忽略),但是不会改变顺序。所以 arr
数组的内容是 [3,1,2,4]
, arr.length
为 4
,且 arr[2]
(数组的第三个元素)为 2
。
英文原文地址:https://typeofnan.dev/10-javascript-quiz-questions-and-answers/
作者:Nick Scialli
想要获取炫酷的页面特效,可访问:js代码特效 栏目!!
以上是分享 10 個提升 JavaScript 技能的測驗問答的詳細內容。更多資訊請關注PHP中文網其他相關文章!