Javascript mülakat sorusu: [1,2,3] .sum () çalıştırın

Nov 17 2020

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

8 Dai Nov 17 2020 at 03:09

Ö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 );

6 VLAZ Nov 17 2020 at 03:26

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.

2 LuisLimas Nov 17 2020 at 03:06

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)