Javascript mülakat sorusu: [1,2,3] .sum () çalıştırın
Javascript mülakat sorusu: ve , [1,2,3].sum()kullanmadan kodun tam olarak çalışmasını sağlayın .PrototypeObject.definePropertyObject.defineProperties
Bir röportaj sorusu olduğundan, onu çalıştırmanın yolları olduğunu varsayıyorum.
Herhangi bir yardım / işaret yönü takdir edilir.
Teşekkürler
Yanıtlar
Önsöz: Bunun gibi sorular, birisinin gerçekten "iyi" bir programcı olduğunu göstermez, bu sadece , daha sürdürülebilir koda götürmeyen dildeki hilelere aşina oldukları anlamına gelir . Düzenli olarak bunun gibi hileler kullanan bir şirket veya ekip için çalışmaktan çekinirim.
(Ve benim kişisel durumda: Ben Microsoft'ta bir GD iken Chakra JavaScript motoru üzerinde çalıştı ve ben düşünmek istiyorum ben çok iyi JavaScript / ECMAScript'i biliyorum ve hala bu olmadan yapılabilir konusunda uzun bir süre düşünmek zorunda prototypeveya kullanarak defineProperty- bu yüzden doğru bir cevap bekliyorlarsa bunun iyi bir teknik mülakat sorusu olduğunu düşünmüyorum - ama bu sizi mülakatı yapan kişiye soru sormaya yönlendirecek bir mülakat sorusuysa, o zaman bu farklıdır).
Seçenek 1: Genel hata işleyici:
İşte korkunç bir yol:
window.addEventListener( 'error', function( e ) {
if( e.error instanceof ErrorEvent || e.error instanceof TypeError ) {
const msg = e.error.message;
const suffixIdx = msg.indexOf( ".sum is not a function" );
if( suffixIdx > -1 ) {
const arrayStr = msg.substring( 0, suffixIdx );
const arr = eval( arrayStr ); // <-- lolno
const total = arr.reduce( ( sum, e ) => sum + e, 0 );
console.log( total ); // 6
}
}
} );
[1,2,3].sum()
@NenadVracar, evalyerel kullanmasına rağmen kaçınan basitleştirilmiş bir sürüm yayınladı try:
try {
[1,2,3].sum()
} catch (err) {
const result = err.message
.match(/\[(.*?)\]/)[1]
.split(',')
.reduce((r, e) => r + +e, 0)
console.log(result)
}
2. Seçenek: Geçersiz Kıl Arrayyapıcısı
Daha eski bir JavaScript motoru kullanıyorsanız (2010 veya ECMAScript 5'ten önce yapılmış), kurucuyu geçersiz kılan bir komut dosyası Array, komut dosyası bir dizi değişmeziyle karşılaştığında bu kurucu kullanacaktır ve .sumyöntem şu şekilde eklenebilir:
Array = function() { // <-- THIS WILL NOT WORK IN BROWSERS MADE AFTER 2010!
this.sum = function() {
var total = 0;
for( var i = 0; i < this.length; i++ ) {
total += this[i];
}
return total;
};
};
let total = [1,2,3].sum();
console.log( total );
3. Seçenek: Mülkte gizlice davranmak prototype:
Diğerlerinin yorumlarda belirttiği gibi, prototypeüyeyi yine de değiştirebilir veya Object.definePropertybu üyelere dizeler olarak erişirseniz kullanabilirsiniz :
Array[ 'proto' + 'type' ].sum = function() {
var total = 0;
for( var i = 0; i < this.length; i++ ) {
total += this[i];
}
return total;
};
let total = [1,2,3].sum();
console.log( total );
Burada çizgileri ne kadar aşabiliriz?
Aşağıdaki satırın çalışmasını istediğimizi varsayarsak [1, 2, 3].sum();, çok kolay bir şekilde bir şeyler yaptırabiliriz . Otomatik noktalı virgül ekleme kuralları nedeniyle , bir dizi olmak için sahip olduğunuz şeyin gerekli olmadığını unutmayın. Bu dizi olabilir erişim ile virgül operatörü içinde.
({3: {sum: () => console.log(6)}}) //<-- object
[1,2,3].sum(); //<-- array access
Veya daha açık hale getirmek için, işte eşdeğer kod:
const obj = {
3: {
sum: () => console.log(6)
}
};
obj[3].sum(); //<-- array access
Ne sumyapılması gerektiğine dair bir tanım görmediğim için , yukarıda listelenen tüm gereksinimleri kapsar - prototip saçmalığı yok, ekstra özellik yok.
Tamam, teknik olarak sumdeğil özetlemek şey, ama burada bir geçici çözüm: şöyle tanımlıyoruz
sum: (a, b) => a + b
Şimdi, teknik olarak iki sayıyı toplayan bir fonksiyon. Sonuçta, 1, 2, 3çağrılmadan önce görünen diziyi toplamaya gerek yoktur sum.
Bu tek yol:
[1,2,3].__proto__.sum = () => { console.log('this runs!'); }
[1,2,3].sum();
Teknik olarak kullanmıyorsun Prototype, kullanıyorsun __proto__. Wich, farklı bir adla aynıdır ... (ancak yalnızca örnekler için)