這篇文章運(yùn)用簡單易懂的例子給大家介紹JavaScript中常見的易錯(cuò)題,代碼非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
創(chuàng)新互聯(lián)建站專注于撫寧網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供撫寧營銷型網(wǎng)站建設(shè),撫寧網(wǎng)站制作、撫寧網(wǎng)頁設(shè)計(jì)、撫寧網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造撫寧網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供撫寧網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。1. 數(shù)組排序比較
看以下數(shù)組,在各種排序操作后都下輸出什么?
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
這里有幾個(gè)概念在起作用。首先,array 的 sort
方法對原始數(shù)組進(jìn)行排序,并返回對該數(shù)組的引用。這意味著當(dāng)你調(diào)用 arr2.sort()
時(shí),arr2
數(shù)組內(nèi)的對象將會(huì)被排序。
當(dāng)你比較對象時(shí),數(shù)組的排序順序并不重要。由于 arr1.sort()
和 arr1
指向內(nèi)存中的同一對象,因此第一個(gè)相等測試返回 true
。第二個(gè)比較也是如此:arr2.sort()
和 arr2 指向內(nèi)存中的同一對象。
在第三個(gè)測試中,arr1.sort()
和 arr2.sort()
的排序順序相同;但是,它們指向內(nèi)存中的不同對象。因此,第三個(gè)測試的評估結(jié)果為 false
。
2. set 的對象
把下面的 Set
對象轉(zhuǎn)成一個(gè)新的數(shù)組,最后輸出什么?
const mySet = new Set([{ a: 1 }, { a: 1 }]); const result = [...mySet]; console.log(result);
答案和解析
答案: [{a: 1}, {a: 1}]
盡管 Set 對象確實(shí)會(huì)刪除重復(fù)項(xiàng),但是我們用 Set 創(chuàng)建的兩個(gè)值是對內(nèi)存中不同對象的引用,盡管它們有相同的鍵值對。這與 { a: 1 } === { a: 1 }
的結(jié)果為 false
的原因相同。
如果集合是用對象變量創(chuàng)建的,例如 obj = {a: 1}
,new Set([obj,obj])
將會(huì)只有一個(gè)元素,因?yàn)閿?shù)組中的兩個(gè)元素都引用了內(nèi)存中的同一對象。
3. 深層對象的可變性
下面的對象代表用戶 Joe 和他的狗 Buttercup。我們用 Object.freeze
保存對象,然后嘗試更改 Buttercup 的 name。最后會(huì)輸出什么?
const user = { name: 'Joe', age: 25, pet: { type: 'dog', name: 'Buttercup', }, }; Object.freeze(user); user.pet.name = 'Daffodil'; console.log(user.pet.name);
答案和解析
答案:Daffodil
Object.freeze
將會(huì)使對象淺凍結(jié),但不會(huì)保護(hù)深層屬性不被修改。在這個(gè)例子中,不能對 user.age
進(jìn)行修改,但是對 user.pet.name
進(jìn)行修改卻沒有問題。如果我們覺得需要保護(hù)一個(gè)對象,避免其“從頭到尾”發(fā)生改變,則可以遞歸地應(yīng)用 Object.freeze
或使用現(xiàn)有的“深度凍結(jié)”庫。
4. 原型繼承
在下面的代碼中,有一個(gè) Dog
構(gòu)造函數(shù)。我們的 dog 顯然有 speak 這個(gè)操作。當(dāng)我們調(diào)用 Pogo 的 speak 時(shí),會(huì)輸出什么?
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());
答案和解析
答案:woof
每次創(chuàng)建一個(gè)新的 Dog
實(shí)例時(shí),我們都會(huì)將該實(shí)例的 speak
屬性設(shè)置為返回字符串 woof
的函數(shù)。由于每次我們創(chuàng)建一個(gè)新的Dog
實(shí)例時(shí)都要設(shè)置該值,因此解釋器不會(huì)沿著原型鏈去找 speak
屬性。結(jié)果就不會(huì)使用 Dog.prototype.speak
上的 speak
方法。
5. Promise.all 的解決順序
在這個(gè)問題中,我們有一個(gè) timer
函數(shù),它返回一個(gè) Promise
,該 Promise 在隨機(jī)時(shí)間后解析。我們用 Promise.all
解析一系列的 timer
。最后的輸出是什么,是隨機(jī)的嗎?
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 無關(guān)。我們能夠可靠地依靠它們按照數(shù)組參數(shù)中提供的相同順序返回。
6. Reduce 數(shù)學(xué)
數(shù)學(xué)時(shí)間!輸出什么?
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
時(shí),聚合器的初始值(在此稱為 agg
)在第二個(gè)參數(shù)中給出。在這種情況下,該值為 1
。然后可以如下迭代函數(shù):
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”
不幸的是,我們的短路評估將無法按預(yù)期工作: notifications !== 1 && 's'
評估為 false
,這意味著我們實(shí)際上將會(huì)輸出 You have 1 notificationfalse
。如果希望代碼段正常工作,則可以考慮條件運(yùn)算符: ${notifications === 1 ? '' : 's'}
。
8. 展開操作和重命名
查看以下代碼中有單個(gè)對象的數(shù)組。當(dāng)我們擴(kuò)展該數(shù)組并更改 0 索引對象上的 firstname
屬性時(shí)會(huì)發(fā)生什么?
const arr1 = [{ firstName: 'James' }]; const arr2 = [...arr1]; arr2[0].firstName = 'Jonah'; console.log(arr1);
答案和解析
答案: [{ firstName: "Jonah" }]
展開操作符會(huì)創(chuàng)建數(shù)組的淺表副本,這意味著 arr2
中包含的對象與 arr1
所指向的對象相同。所以在一個(gè)數(shù)組中修改對象的 firstName
屬性,也將會(huì)在另一個(gè)數(shù)組中更改。
9. 數(shù)組方法綁定
在以下情況下會(huì)輸出什么?
const map = ['a', 'b', 'c'].map.bind([1, 2, 3]); map(el => console.log(el));
答案和解析
答案: 1 2 3
當(dāng) ['a', 'b', 'c'].map
被調(diào)用時(shí),將會(huì)調(diào)用 this'
值為 '['a','b','c']
的 Array.prototype.map
。但是當(dāng)用作 引用
時(shí), Array.prototype.map
的引用。
Function.prototype.bind
會(huì)將函數(shù)的 this
綁定到第一個(gè)參數(shù)(在本例中為 [1, 2, 3]
),用 this
調(diào)用Array.prototype.map
將會(huì)導(dǎo)致這些項(xiàng)目被迭代并輸出。
10. set 的唯一性和順序
在下面的代碼中,我們用 set
對象和擴(kuò)展語法創(chuàng)建了一個(gè)新數(shù)組,最后會(huì)輸出什么?
const arr = [...new Set([3, 1, 2, 3, 4])]; console.log(arr.length, arr[2]);
答案和解析
答案: 4 2
set
對象會(huì)強(qiáng)制里面的元素唯一(集合中已經(jīng)存在的重復(fù)元素將會(huì)被忽略),但是不會(huì)改變順序。所以 arr
數(shù)組的內(nèi)容是 [3,1,2,4]
, arr.length
為 4
,且 arr[2]
(數(shù)組的第三個(gè)元素)為 2
。
關(guān)于JavaScript的易錯(cuò)題和答案解析就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。