Javascript 角度参考误解

Javascript 角度参考误解,javascript,angularjs,Javascript,Angularjs,正如我刚刚意识到的,我不太了解角度的范围。仔细看看var Cart:我试图访问cartimes变量,就像cartimes:cartimes一样,但这不起作用。如果我把它包装到函数中,我会从闭包中得到这个变量(正如chrome开发工具所说)。有人能解释一下区别吗?为什么我不能直接从购物车对象访问购物车项目?谢谢 p.S.尝试对变量使用this而不是var,没有任何区别 .factory('Cart', function(FirebaseUrl, $firebaseArray, $firebaseO

正如我刚刚意识到的,我不太了解角度的范围。仔细看看
var Cart
:我试图访问
cartimes
变量,就像
cartimes:cartimes
一样,但这不起作用。如果我把它包装到函数中,我会从闭包中得到这个变量(正如chrome开发工具所说)。有人能解释一下区别吗?为什么我不能直接从
购物车
对象访问
购物车项目
?谢谢

p.S.尝试对变量使用
this
而不是
var
,没有任何区别

.factory('Cart', function(FirebaseUrl, $firebaseArray, $firebaseObject, $state, Auth) {

    var cartsRef = new Firebase(FirebaseUrl + '/carts');
    var userId, cartRef, cartItems;

    Auth.$onAuth(function(authData) { // triggers on entering the page
      userId = authData && authData.uid;
      cartRef = new Firebase(cartsRef + '/' + userId);
      cartItems = $firebaseArray(cartRef);
    });

    var Cart = {
      getCartItems: function() {
        return cartItems;
      },
      cartItems: cartItems // this won't work
    };  

    return Cart;
  });
编辑:为了理解我的问题,我将提供一段控制器代码:

 .controller('CartCtrl', function(Cart, Auth) {
    var cartCtrl = this;
    cartCtrl.cartItems = Cart.getCartItems(); // returns items
    cartCtrl.cartItems1 = Cart.cartItems; // returns undefined. Why?

当您执行
cartItems:cartItems
时,您正在将该属性分配给
cartItems
当前值,该值不算什么

当您执行
getCartItems:function()…
时,直到稍后调用该函数时,您才会访问
cartItems
。只有在调用时,您才能访问已设置的
cartItems

您所看到的不是
$scope
,也不是JS scope,而是引用。你在做一个“按价值”的分配,这在这两个不同的时间点是不同的

下面是一个简单的例子:

var foo = 'foo';

var fooAsValue = foo;

function fooAsFunction () {
  return foo;
}

foo = 'bar';

console.log(fooAsValue) // "foo"
console.log(fooAsFunction()) // "bar"
如您所见,当您将
fooAsValue
分配给
foo
时,您将从该时间点获取值--
'foo'

当您更改
foo
时,另一个变量,
fooAsValue
,已经从以前捕获了它的值——这不会改变。当您执行
fooAsFunction
时,在将其分配给
'bar'
后,您将收到该新值,因为您现在引用的变量具有新值


如果它是一个对象引用
,这将是不同的,它将更像一个指针

让我们看看这个例子:

var anObject = {
  foo: {bar: 'foobar'}
};

var fooAsReference = anObject.foo;

anObject.foo.bar = 'hello world';

console.log(fooAsReference) // {bar: 'hello world'}
这就是事情有点变化的地方。正在对对象的属性进行赋值,该属性指向另一个对象

这里我们指向
anObject.foo
,我们更改了
anObject.foo.bar
,我们实际上保留了原始引用,因为它没有更改——更改发生在对象树的下一步。我们看到了这种变化,因为我们的参考并没有改变。改变的是我们引用的对象内部的值,而不是我们指向的值

这有点棘手,但如果您亲自体验这两种不同的场景,即使它只是一个带有几个变量和一些控制台输出的空白文件,它也会开始真正的点击


所以要把这一切重新组合起来

cartItems:cartItems
向尚未有值的
cartItems
赋值。所以这个是空的

getCartItems
返回
cartItems
,在调用它时,它可能有一个值。这是因为
Auth.$onAuth
已激发,并且分配
cartItems=$firebaseArray(cartRef)已生成。然后在该赋值之后调用函数
getCartItems
,然后得到值

你能做什么 我们可以将真理的单一来源转化为自身,而不是让
Cart.cartimes
指向我们知道可以改变的东西。更新该属性,而不是单独的变量


还可以将命名简化为简单的
Cart.items
,因为我们已经知道“这些项目属于购物车”:

您如何/从何处尝试访问
cartItems
?您提供的代码不是一个控制器,而是一个工厂,因此我不认为这与角度范围或控制器作为syntaxfrom
var userId、cartRef、carttItems有什么关系
,其中我定义了变量,在
Auth.$onAuth
中可以看到
cartItems=$firebaseArray(cartRef)我的意思不是
$scope
,而是JS scope。”Aaron编辑了这个问题。也许这会让它更清楚谢谢你的宽泛回答!我想我明白了:)我在第二个示例中犯了一个小小的错误,但将更新:)第二次更新,为您的特定问题提供了一个潜在的解决方案是的,我认为这个解决方案更好。再次感谢!
var Cart = {cartItems: []};

Auth.$onAuth(function () {
  // ...
  // Now we're talkin!
  Cart.cartItems = $firebaseArray(cartRef);
});

return Cart;