2015-07-10 5 views
5

Я пытаюсь создать корзину покупок для обучения. Я следующие кодыИспользование самоназывающих анонимных функций

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

Но этот код бросками следующая ошибка

Uncaught TypeError: Cannot set property 'createCart' of undefined

Проведя несколько часов в Интернете и после некоторых уроков я сделал следующие изменения кода, а затем начал работать.

Но все-таки я не понимаю, что я сделал здесь

var cart = (function (cart) { 

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


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

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

Может кто-нибудь, пожалуйста, объясните мне, почему код начал работать после прохождения cart || {} выражения в анонимную функцию? Некоторые подробные объяснения были бы замечательными. :)

+1

телега не определено в cart.createCart. Вы должны использовать эту функцию внешней корзины. –

+1

функция ожидает 'cart' в качестве параметра, без прохождения' cart || {} 'вы ничего не проходите, поэтому' cart' будет неопределенным. помните, что IIFE имеют полностью изолированную область –

ответ

3

Таким образом, без переменной, передаваемой в область действия.

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

Однако, если передать переменную в контексте:

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

Так IIFE выглядит следующим образом:

(function() { })(); 

так игнорируя function вы получите ()(); в этой второй паре в скобках вы передаете параметры в function в первом наборе. Это связано с тем, что IIFE создает совершенно новую чистую область. Вот почему мы используем IIFE, потому что он может изолировать глобальные переменные, которые мы используем в них.

так что если у вас есть это:

<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> 

Так IIFE являются большими для контроля того, что вы имеете в областях.

cart || {} является нулевым COALESCE JavaScript, поэтому он говорит, пройти в корзину, но если он пустой дать ему пустой объект

2

Потому что вы в процессе декларирования телеги переменной пока не инстанцированный. Когда вы вместо этого передаете пустой объект (это то, что будет оценивать cart || {}, оно добавит метод к этому объекту, вернет его, а затем будет тележка). Вторая функция имеет то же значение, что и следующий код:

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


    return cart; 
}()); 

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

Я не запускать этот код, но от чтения через него:

В первом примере, на третьей строке, где вы называете cart.createCart, объект корзину не но существует. Функция еще не вернула объект, который он сам ссылается на внутренне!

Во втором примере корзину объект до сих пор не существует, но вы предоставили запасной вариант на новый пустой объект:

cart || {} 

Таким образом, внутри функции, корзина является новым пустой объект, к которому вы применяете свойство createCart.

EDIT: Альтернативная функция Эрика Лундгрена, только что опубликованная, - это то, что вам нужно. Это значение понятнее, поскольку объект тележки явно создается внутри функции. Используйте это! :)

Единственное, что я хотел бы добавить, это то, что у вас на самом деле нет причин делать все это внутри непосредственно вызываемого выражения функции в данном конкретном случае. Там нет ничего, что нуждается в определении области. Так что это будет делать:

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

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

С помощью этого кода:

(cart || {}) 

Вы передаете сферу функции и, если он пуст, вы передаете пустой объект ({}). Кажется, у вас есть объект cart, и когда вы делаете var cart = (function ...., вы его переопределяете.

Может быть, ваш объект должен быть назван Cart с прописными буквами, и это тоже работает:

var cart = (function() { 
     Cart.createCart()... 
    }); 
Смежные вопросы