0

问题:Uncaught TypeError: Object #<Object> has no method 'push'在控制台中。

http://jsfiddle.net中的代码

4

7 回答 7

3

更改存储项目 id(Cart) 并重试,看起来以前存储在“购物车”下的项目 id 不是 json 数组,正如评论部分中建议的 @dc5

UPD:试试这个http://jsfiddle.net/vJkBQ/4/

HTML

<div id='cart'></div>
<input type="button" id="add" value="Add To Cart item 1" />
<input type="button" id="add2" value="Add To Cart item 2" />

Javascript

//TODO: move from globals
var storageName = 'myCART';

$(document).ready(function () {
    var item = {
        DepartmentID :333,
        CategoryID:117,
        BrandID:19,
        BrandImage:"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
        BrandName:"General",
        ID:711
    };
    var item2 = {
        DepartmentID :123,
        CategoryID:321,
        BrandID:18,
        BrandImage:"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
        BrandName:"Common",
        ID:712
    };

    localStorage.clear(storageName);
    $('#add').click(function(){
       addToCart(item);
    });

    $('#add2').click(function(){
       addToCart(item2);
    });
});

function addToCart(item){
    //by @slebetman   
    var items = JSON.parse(localStorage.getItem(storageName));
    if (! (items instanceof Array) ) {
        items = [];
    }

    var itemIndex = getItemIndexById(items, item.ID);    
    if(typeof(itemIndex) === 'number'){
        items[itemIndex].quantity++;
    }
    else{
        item.quantity = 1;
        items.push(item);
    }

    localStorage.setItem(storageName, JSON.stringify(items));
    console.log(localStorage.getItem(storageName));
}

//find search item index
function getItemIndexById(items, id){
    for(var i = 0; i < items.length; i++){
        if(items[i].ID == id){
            return i;
        }
    }

    return false;
}
于 2013-09-04T06:07:33.310 回答
3

表达方式:

JSON.parse(localStorage.getItem(storageName))

很可能不会返回数组。在这种情况下,声明:

var oldStorage = JSON.parse(localStorage.getItem(storageName)) || [];

是不够的。

你应该做的是这样的:

var oldStorage = JSON.parse(localStorage.getItem(storageName));
if (! (oldStorage instanceof Array) ) {
    oldStorage = [];
}

这是一种检测数组的简单方法。还有更高级的方法,例如检查是否存在.length等,可以检测数组和类似数组的对象,以及在 Array 对象已被覆盖或跨 iframe 工作的情况下检测数组。


补充回答:

您已经更改了很多代码,但问题仍然相同。该行:

if (items != null) {

不足以检查 items 是一个数组。你应该这样做:

if ( items instanceof Array ) {

以确保它确实是一个数组。

此外,在 else 块中:

}else{
    console.log('Cart is empty, preparing new cart array');
    items.push(item);

console.log消息说正在准备一个新阵列。然而,它的存在是因为代码没有初始化一个新数组,而是items像使用数组一样使用变量。你应该这样做:

}else{
    console.log('Cart is empty, preparing new cart array');
    items = [];
    items.push(item);

警告:

但是,毕竟,请注意我的问题的评论者。如果你从头开始写这整件事,而不是做我建议的事情会解决你所有的问题。但是,如果您正在做的是修改其他人的代码,那么很可能Cart是以不同于您预期的格式存储的。

console.log(localStorage['Cart'])在致电之前做,JSON.parse并在此处发布您的结果。问题在于浏览器上的本地存储,通常无法在其他人的机器上复制。

于 2013-09-04T06:30:39.417 回答
1

JSON.parse(localStorage.getItem(storageName)) 

总是返回一个数组?如果是这样,问题在于并非所有浏览器都支持 push 方法。如果缺少,您可以使用此代码段添加它:

if(!Array.prototype.push){
    Array.prototype.push=function(x){
        this[this.length]=x;
        return true
    }
};

这段代码只是一个开始,你绝对可以改进它

于 2013-09-04T06:09:47.487 回答
1

你可以使用你可以调用Array.prototype.push()一个对象使用call().

JSFiddle

JavaScript

function appendToStorage(storageName, data){
    var oldStorage = JSON.parse(localStorage.getItem(storageName)) || [];
    Array.prototype.push.call(oldStorage, data);
    localStorage.setItem(storageName,JSON.stringify(oldStorage));
}
于 2013-09-04T06:31:46.567 回答
1

JSON.parse返回一个对象或null. 所以在这里你不知道你有一个对象还是一个数组。

JSON.parse(localStorage.getItem(storageName)) || [];

您可以改用它:

function appendToStorage(storageName, data){
    var oldStorage = JSON.parse(localStorage.getItem(storageName)) || {};
    if (oldStorage != null){
        $(oldStorage).extend(data);
        localStorage.setItem(storageName,JSON.stringify(oldStorage));
    } 
}

$.extend() 会将您的项目添加到另一个 JSON 对象。信息在这里

于 2013-09-04T06:37:17.910 回答
0

您的“项目”不是数组,您不能对它使用推送方法。

于 2013-09-04T05:50:16.307 回答
0

对象没有'push'方法,你可以这样做!

function appendToStorage( storageName, data ) {
    var oldStorage = JSON.parse( localStorage.getItem( storageName ) ) || {},
        push = Array.prototype.push;
    push.call( oldStorage, data );
    // oldStorage.data = data;
    localStorage.setItem(storageName,JSON.stringify(oldStorage));
}
于 2013-09-04T05:52:23.660 回答