2015-07-10 12 views
5

Sto cercando di creare un carrello acquisti a scopo di apprendimento. Ho seguito i codiciUtilizzo di funzioni anonime autoinvitrici

HTML

<div id="MyCart" class="product-cart"> 
    <ul> 
     <li class="item"></li> 
     <li class="item"></li> 
     <li class="item"></li> 
    </ul> 
</div> 

js

var cart = (function() { 

    cart.createCart = function (cartId) { 
     console.log(cartId); 
     cartId = document.getElementById(cartId); 
    } 


    return cart; 
}()); 

var shoopingCart = cart.createCart("MyCart"); 

Ma questo codice genera seguente errore

Uncaught TypeError: Cannot set property 'createCart' of undefined

Dopo aver trascorso qualche ora in internet e seguendo alcuni tutorial ho seguito le modifiche al codice e poi ha iniziato a funzionare.

Ma ancora non capisco quello che ho fatto qui

var cart = (function (cart) { 

    cart.createCart = function (cartId) { 
     console.log(cartId); 
     cartId = document.getElementById(cartId); 
    } 


    return cart; 
}(cart || {})); 

var shoopingCart = cart.createCart("MyCart"); 

qualcuno può spiegare a me perché il codice ha iniziato a lavorare dopo il passaggio cart || {} espressione nella funzione anonima? Qualche spiegazione dettagliata sarebbe grandiosa. :)

+1

carrello non è definito in cart.createCart. Dovresti usare quella funzione del carrello esterno. –

+1

la funzione si aspetta 'carrello' come parametro, senza passare' carrello || {} 'stai passando nulla, quindi' cart' sarà indefinito. ricorda che l'IIFE ha un ambito completamente isolato –

risposta

3

Quindi senza la variabile passata nell'ambito.

var cart = (function (cart) { 

    // can't add a property or method onto undefined. 
    cart.createCart = function (cartId) { 
     console.log(cartId); 
     cartId = document.getElementById(cartId); 
    } 


    return cart; 
}()); // without any value here^cart will be undefined. 

var shoopingCart = cart.createCart("MyCart"); 

Tuttavia, se si passa la variabile al contesto:

var cart = (function (cart) { 

    // cart now is an object which you can attach a property or method 
    cart.createCart = function (cartId) { 
     console.log(cartId); 
     cartId = document.getElementById(cartId); 
    } 


    return cart; 
}(cart || {})); // pass in cart, or if it is null a new object {} 

var shoopingCart = cart.createCart("MyCart"); 

Quindi, un IIFE assomiglia a questo:

(function() { })(); 

quindi ignorando il function si ottiene ()(); in quella seconda coppia di parentesi si passano i parametri allo function nel primo set. Questo perché IIFE crea un nuovo ambito pulito. Questo è il motivo per cui usiamo IIFE perché può isolare le variabili globali che usiamo in esse.

quindi se avete questo:

<script> 

var someGlobalVariable = "hey"; 

(function() { 

    // using someGlobalVariable here will be fine 

    var myIIFEScopedVariable = "ho"; 

})(); 

// trying to access myIIFEScopedVariable here will fail because again, it hasn't been defined here. 

</script> 

Così IIFE di sono grandi per il controllo di quello che hai in ambiti.

Il cart || {} è un nulla fondono JavaScript, così si dice, passano in spesa ma se è nulla dargli un oggetto vuoto

2

Perché tu sei in corso di dichiarare la variabile della spesa non è ancora creata un'istanza. Quando invece si passa in un oggetto vuoto (che è ciò che verrà valutato da cart || {} aggiungerà il metodo a tale oggetto, lo restituirà e il carrello sarà quell'oggetto.) Ciò che la seconda funzione fa è essenzialmente la stessa del seguente codice:

var cart = (function() { 
    var cart = {}; 
    cart.createCart = function (cartId) { 
     console.log(cartId); 
     cartId = document.getElementById(cartId); 
    } 


    return cart; 
}()); 

var shoopingCart = cart.createCart("MyCart"); 
2

non ho eseguito questo codice, ma dalla lettura attraverso di essa:

Nel vostro primo esempio, sulla linea tre, dove si chiama cart.createCart, l'oggetto carrello non lo fa esiste ancora. La funzione non ha ancora restituito l'oggetto a cui si riferisce internamente!

Nel secondo esempio, il carrello oggetto ancora non esiste, ma hanno fornito un ripiego a un nuovo oggetto vuoto:

cart || {} 

Così, all'interno della funzione, carrello è un nuovo oggetto vuoto, a cui si applica la proprietà createCart.

MODIFICA: la funzione alternativa di Erik Lundgren appena pubblicata è ciò di cui hai bisogno. Il suo significato è più chiaro, poiché l'oggetto cart è chiaramente istanziato all'interno della funzione. Usa quello! :)

L'unica cosa che vorrei aggiungere è che in questo caso particolare non si ha alcuna ragione per fare tutto questo all'interno di un'espressione di funzione immediatamente richiamata. Non c'è niente in là che abbia bisogno di essere scoperto. Quindi questo farà:

var cart = {}; 
cart.createCart = function (cartId) { 
    console.log(cartId); 
    cartId = document.getElementById(cartId); 
} 

var shoopingCart = cart.createCart("MyCart"); 
1

Con questo codice:

(cart || {}) 

si passa la portata della funzione e se è vuota, si passa un oggetto vuoto ({}). Sembra che tu abbia un oggetto cart, e quando fai il var cart = (function .... lo stai sovrascrivendo.

Forse l'oggetto deve essere chiamato Cart con lettere maiuscole e funziona troppo:

var cart = (function() { 
     Cart.createCart()... 
    });