Quante incongruenze derivano dall'elevata flessibilità di Javascript?

3

Lo ammetto, non ho ancora imparato il linguaggio, ma la mia esperienza con esso mi dice che Javascript è un linguaggio molto flessibile, che consente l'ereditarietà prototipale, la digitazione dinamica, funzioni come cittadini di prima classe e così tante altre cose interessanti cose. Penso che tali caratteristiche portino alcune incongruenze, ma non è una novità, la maggior parte delle persone sarebbe d'accordo con me. Volevo discutere di esempi specifici che mi hanno infastidito, come "for in" loops:

for(var role in rolesToAdd){
                if(rolesToAdd.hasOwnProperty(role)){
                    // for body
                }
}

Perché dovrei aver bisogno di fare questo? Questo non rompe il concetto di classi ed eredità? Potrei non voler scorrere l'intero prototipo, ma cosa succede se ho ancora bisogno di alcuni degli attributi / metodi dal genitore diretto di un oggetto, per esempio?

Inoltre, sarei molto grato se qualcuno potesse spiegarmi perché l'interprete non consente che anche le variabili globali / locali condividano lo stesso ambito, quando c'è sicuramente un modo in cui potrebbe distinguere l'una dall'altra. Mi piace in:

var foo = function() {
        var wth = bar();
        var bar = wth;
        // body...
}();

function bar(){
    return 'bar mitzvah';
}

Si può vedere che, anche se la nostra barra locale è stata dichiarata dopo la chiamata alla nostra barra globale, il valore della barra nell'oscilloscopio di foo rifletterà sempre la barra locale, che manterrà 'indefinito'. Non è uno strano comportamento? Mi piacerebbe se i programmatori senior di Js mi illuminassero su questo e mi mostrassero cosa si ottiene da queste caratteristiche apparentemente strane e se gli svantaggi che ho menzionato qui sono validi.

    
posta ericmux 15.05.2013 - 03:08
fonte

2 risposte

6

Why should I need to this? Doesn't this break the concept of classes and inheritance? I might not want to loop through the whole prototype, but what if still need some of the attributes/methods from an object's direct parent, for example?

JavaScript è essenzialmente un linguaggio funzionale che ha uno stile imperativo. JavaScript può fingere classi ed ereditarietà, ma non sono concetti di prima classe ben supportati. Pertanto, colpiscono naturalmente alcuni muri quando vuoi esprimere le idee in questo modo. Ci sono alcuni buoni trattamenti di JavaScript come OOP su Internet . È molto probabile che se colpisci la testa contro un muro con JavaScript, qualcun altro prima di farlo anche tu.

Also, I would be most grateful if someone could explain me why the interpreter doesn't allow synonymous global/local variables to share the same scope, when there is certainly a way he could distinguish one from the other.

Il sistema di tipo dinamico significa che l'interprete non può dire quale sia il tipo di bar . Come nota aggiuntiva, JavaScript esegue anche sollevamento automatico .

Quando ho eseguito il codice di esempio, ho ricevuto un reclamo perché foo è un'espressione di funzione immediatamente richiamata, quindi bar non è definito in quel punto.

TypeError: bar is not a function
var wth = bar();

Ma supponiamo che non sia stato il caso. Quando assegni wth a bar() , vede che stai tentando di richiamare bar come callable. function bar() è lo zucchero quasi sintattico per var bar = function() . Nota il link nel commento di Neil sul perché è "quasi".

Il sistema di tipi non può distinguere tra var bar = 5; e var bar = function() { return 5; } perché puoi fare cose cattive come la seguente:

var i = 5;
console.log(typeof i);
i = 'hello';
console.log(typeof i);
i = function() { return 'f'; }
console.log(typeof i);
console.log(typeof i());

L'output sarà:

number
string
function
string

Questo è ciò che intendo per il sistema di tipo dinamico non può dire quale sia il tipo di bar ; una variabile tiene semplicemente i dati e i dati hanno un tipo. Quindi se provi a fare qualcosa del tipo:

var i = 5;
console.log(i());

Ti ritroverai con un errore di tipo perché i non è un callable e stai tentando di usarlo come uno.

    
risposta data 15.05.2013 - 03:51
fonte
5

Si presume che tu voglia tutte le proprietà iterabili di un oggetto, devi solo usare hasOwnProperty se pensi che ci siano metodi o proprietà nell'oggetto o nel suo prototipo che avrebbero dovuto essere contrassegnati come non enumerati ma non lo erano. Sembra che tu stia combattendo contro il linguaggio in cui è scontato che tu voglia che tutte le proprietà dell'oggetto vengano ripetute, inclusi tutti quelli che ha ereditato. Devi ricordarlo

JavaScript non ha classi

questo è importante, puoi simulare le classi usando le librerie e le classi possono essere aggiunte in ES6 ma attualmente ha un'ereditarietà basata su prototipo che ti brucia se provi a fingere che sia esattamente la stessa di una classe.

Il tuo secondo problema riguarda l'ambito funzionale,

var foo = function() {
    var wth = bar();
    var bar = wth;
    // body...
}();

function bar(){
    return 'bar mitzvah';
} 

è davvero.

var foo;

function bar(){
    return 'bar mitzvah';
} 
foo = (function() {
    var wth;
    var bar = wth;
    wth = bar();        
    // body...
})();//you want parentheses here I'm pretty sure.

Il problema è che le nuove variabili sono issate in cima all'ambito locale (funzionale), il che significa che anche se non hai ancora ridefinito la barra, per quanto riguarda la lingua che hai.

Onestamente non conosco il vantaggio che avevo in mente quando è stato creato, se vuoi davvero sapere dovresti chiedere a Brendan Eich (no seriamente è stato conosciuto per rispondere a queste domande su twitter ), ma è una caratteristica che non sono sicuro che molte persone che usano JavaScript debbano necessariamente occuparsene.

    
risposta data 28.05.2013 - 15:59
fonte

Leggi altre domande sui tag