Come usi la digitazione anatra in javascript senza controllare sempre le proprietà e i metodi?

11

So che javascript usa la digitazione anatra e all'inizio pensavo che questo avrebbe reso il polimorfismo facile rispetto a linguaggi strongmente tipizzati come C #. Ma ora le mie funzioni che prendono argomenti sono disseminate di cose come:

if(myObj.hasSomeProperty())

o

if(myObj.hasSomeMethod())

o

if(isNumber(myParam))

ecc.

Questo è davvero brutto per me. Vengo da uno sfondo C # e trovo che le interfacce definite siano molto migliori.

Mi chiedo se sto tentando in modo errato di applicare strategie che sono efficaci in linguaggi tipizzati staticamente e c'è un modo migliore per farlo in javascript?

So che non potrei semplicemente controllare, ma rintracciare gli errori di run time di JavaScript può essere un incubo poiché non sempre avvengono dove si verifica effettivamente l'errore nel codice.

    
posta Legion 26.12.2015 - 01:59
fonte

3 risposte

11

How do you use duck typing in javascript without always checking for properties and methods?

Semplice: non sempre controlli proprietà e metodi.

In Ruby, ciò che chiamate è chiamato "digitazione di un pollo". In un linguaggio con dattilografia dinamica, ti basta credere che il chiamante ti passi un oggetto adatto. È compito del chiamante onorare la sua parte del contratto.

I know javascript uses duck typing and at first I thought this would make polymorphism easy compared to strongly typed languages like C#.

Stai confondendo più assi ortogonali di digitazione qui. Ci sono quattro assi ortogonali di battitura:

  • Quando : digitazione dinamica (i tipi non sono conosciuti e controllati fino al runtime) rispetto alla tipizzazione statica (i tipi sono conosciuti e controllati prima del runtime)
  • Cosa : digitazione anatra (i tipi sono basati su comportamento ), tipizzazione strutturale (i tipi sono basati su struttura ) e digitazione nominale (i tipi sono basati su nome )
  • Puoi vederli? digitando esplicitamente (i tipi devono essere esplicitamente annotati) rispetto alla tipizzazione implicita (i tipi sono dedotti)
  • strong tipizzazione vs. debole digitazione - potreste aver notato che non ho dato a questo un titolo accattivante né una spiegazione tra parentesi, perché a differenza dei sette termini sopra, che hanno ciascuno una singola definizione precisa universalmente accettata, questi due termini hanno una dozzina di definizioni vagamente semi-ampiamente usate che si contraddicono a vicenda; idealmente dovresti evitare del tutto questi termini e, se devi usarli, definirli con precisione prima

Dato che hai citato C #: è tipicamente tipizzato in modo statico, ma supporta la digitazione dinamica attraverso il tipo dynamic , è tipicamente tipizzato nominalmente, ma i tipi anonimi usano la tipizzazione strutturale e i pattern sintattici (come la sintassi di comprensione delle query LINQ) possono essere argomentato o digitato an tipicamente o tipicamente, è tipicamente tipizzato in modo esplicito ma supporta la digitazione implicita per argomenti di tipo generico e variabili locali (sebbene il caso variabile locale sia piuttosto strano rispetto alla maggior parte delle altre lingue, perché non si può semplicemente lasciare il tipo fuori, devi invece dargli un pseudo-tipo% di var , in altre parole, se vuoi un tipo implicito, devi dirlo esplicitamente). Indipendentemente dal fatto che C # sia strongmente o debolmente tipizzato è una questione di quale definizione dei due termini che si usano, tuttavia, si noti che ci possono essere molti errori di tipo runtime in C #, specialmente a causa della covarianza dell'array non sicuro.

I know I could just not check, but tracking down javascript run time errors can be a nightmare since they don't always happen where the error is actually occurring in the code.

Il debug non è un'abilità facile da imparare. Esistono tuttavia tecniche per facilitare il debugging, ad es. il Saff Squeeze è una tecnica descritta da Kent Beck che utilizza test e refactoring per il debugging:

Hit 'em High, Hit 'em Low:

Regression Testing and the Saff Squeeze

Kent Beck, Three Rivers Institute

Abstract: To effectively isolate a defect, start with a system-level test and progressively inline and prune until you have the smallest possible test that demonstrates the defect.

    
risposta data 26.12.2015 - 05:59
fonte
1

I know I could just not check, but tracking down javascript run time errors can be a nightmare since they don't always happen where the error is actually occurring in the code.

In effetti, la pratica tipica non è controllare. E, sì, questo significa che otterrai errori javascript che vengono riportati altrove dal problema reale. Ma in pratica, non trovo che questo sia un grosso problema.

Quando lavoro in javascript, sto costantemente testando quello che sto scrivendo. Nella maggior parte del codice, ho dei test unitari che vengono eseguiti automaticamente ogni volta che salgo il mio editor. Quando qualcosa va inaspettatamente, lo so quasi immediatamente. Ho una piccola area di codice in cui avrei potuto commettere l'errore, poiché è quasi sempre l'ultima cosa che ho toccato che ha sbagliato.

Quando ottengo un errore di runtime, ho almeno ottenuto la traccia dello stack e, nel caso di un errore nel browser, ho la possibilità di accedere a qualsiasi livello dello stack trace e ispezionare le variabili . È in genere facile risalire da dove proviene il valore errato e quindi risalire al problema originale.

Se sei come me quando ho scritto principalmente in lingue tipizzate staticamente, ho scritto blocchi più grandi di codice prima di testare e non avevo pratica nel tracciare un valore da dove proveniva. Programmare in una lingua come javascript è diverso, devi usare abilità diverse. Sospetto che la programmazione come quella sembra molto più difficile, perché quelle non sono le abilità che hai sviluppato lavorando in altri linguaggi come C #.

Detto questo, penso che ci sia molto da dire per i tipi espliciti. Sono grandi per la documentazione e gli errori di cattura in anticipo. Penso che in futuro vedremo aumentare l'adozione di cose come Flow e Typescript che aggiungono il controllo di tipo statico al javascript.

    
risposta data 26.12.2015 - 22:37
fonte
0

Penso che tu stia facendo la cosa giusta, hai solo bisogno di trovare lo stile che ti piacerà di più. Ecco alcune idee:

  • Invece di if(myObj.hasSomeProperty()) potresti usare if( myobj.prop !== undefined ) . Questo, BTW funzionerà solo in modalità non rigida, in modalità rigorosa dovresti usare if( typeof myobj.prop !== 'undefined' ) .

  • Puoi scaricare alcuni dei tipi di controllo per separare i validatori. Ciò ha il vantaggio di poter saltare la convalida una volta che le interfacce sono mature, ad es. if( is_valid( myobject )) , dove is_valid inizia con if( !DEBUG ) return true; .

  • A volte ha senso clonare l'input in una forma canonica, nel qual caso è possibile raccogliere i vari target di validazione nella funzione / oggetto di clonazione. Per exmaple, in my_data = Data( myobj, otherstuff ) il costruttore di Data può eseguire comodamente tutte le varie convalide in un posto centrale.

  • Potresti usare una libreria che (a un costo di prestazioni) semplificherà la tua convalida del tipo in qualcosa di più elegante. Anche se non seguirai questa strada a lungo termine, potresti trovarti a tuo agio nel tuo stile. Alcuni esempi includono xtype.js , tipo -check , validator.js , ecc.

risposta data 26.12.2015 - 22:06
fonte

Leggi altre domande sui tag