Javascript 使用自调用匿名函数

Javascript 使用自调用匿名函数,javascript,object,anonymous-function,Javascript,Object,Anonymous Function,我正试图建立一个学习目的购物车。我有以下代码 HTML <div id="MyCart" class="product-cart"> <ul> <li class="item"></li> <li class="item"></li> <li class="item"></li> </ul> </div> 但这段

我正试图建立一个学习目的购物车。我有以下代码

HTML

<div id="MyCart" class="product-cart">
    <ul>
        <li class="item"></li>
        <li class="item"></li>
        <li class="item"></li>
    </ul>
</div>
但这段代码会引发以下错误

未捕获的TypeError:无法设置未定义的属性“createCart”

在互联网上花了几个小时并学习了一些教程之后,我对代码做了如下修改,然后它开始工作

但我仍然不明白我在这里做了什么

var cart = (function (cart) {

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


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

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

有人能解释一下为什么代码在将
cart | |{}
表达式传递到匿名函数后开始工作吗?详细解释一下就好了。:)

因此,没有将变量传递到作用域中

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");
所以一种生活是这样的:

(function () { })();
因此忽略
函数
就得到了
()
在第二对括号中,将参数传递给第一组中的
函数。这是因为iLife创建了一个全新的干净范围。这就是为什么我们使用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>

var someGlobalVariable=“嘿”;
(功能(){
//在这里使用someGlobalVariable就可以了
var myIIFEScopedVariable=“ho”;
})();
//尝试在此处访问myIIFEScopedVariable将失败,因为这里没有定义它。
因此,生活对于控制你在范围内拥有的东西来说是很好的


cart | |{}
是一个JavaScript空合并,所以它说,传入cart,但如果它为空,则给它一个空对象

,因为您正在声明cart变量,它还没有实例化。相反,当您传入一个空对象(即
cart | |{}
将对其求值的对象)时,它将向该对象添加方法,返回该方法,然后cart将成为该对象。第二个函数的作用与以下代码基本相同:

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


    return cart;
}());

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

我没有运行此代码,但通过阅读:

在第一个示例中,在第三行调用cart.createCart,对象cart尚不存在。函数尚未返回其内部引用的对象

在第二个示例中,购物车对象仍然不存在,但您提供了一个新空白对象的回退:

cart || {}
因此,在函数内部,cart是一个新的空白对象,您可以对其应用createCart属性

编辑:刚刚发布的Erik Lundgren的替代函数正是您所需要的。它的含义更清楚,因为cart对象在函数中被明确实例化。使用它吧!:)

我要补充的唯一一点是,在这种特殊情况下,您没有任何理由在立即调用的函数表达式中执行所有这些操作。那里没有任何东西需要确定范围。这样做可以:

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

var shoopingCart = cart.createCart("MyCart");
使用此代码:

(cart || {})
您正在传递函数的作用域,如果它为空,则传递一个空对象(
{}
)。似乎您有一个
cart
对象,当您创建
var cart=(函数…
时,您正在覆盖它

也许您的对象必须用大写字母调用
Cart
,并且它也可以工作:

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

cart.createCart中未定义cart。您应该使用该外部cart函数。该函数期望将
cart
作为参数,而不传递
cart |{}
您没有传递任何内容,因此
cart
将未定义。请记住,IIFE有一个完全隔离的作用域
  var cart = (function() {
       Cart.createCart()...
  });