开发者问题收集

JavaScript 中 push() 不起作用

2013-09-04
2047

问题: 未捕获的 TypeError:对象 #<Object> 在控制台中没有方法“push”

代码在 http://jsfiddle.net

3个回答

更改存储项目 ID(购物车)并重试,看起来“购物车”下先前存储的项目 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;
}
Dart
2013-09-04

表达式:

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 的存储格式可能与您预期的格式不同。

请在调用 JSON.parse 之前执行 console.log(localStorage['Cart']) ,然后将结果发布在此处。问题出在您浏览器上的 您的 本地存储上,通常无法在其他人的机器上重现。

slebetman
2013-09-04

JSON.parse(localStorage.getItem(storageName)) 

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

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

此代码只是一个开始,您绝对可以改进它

prmph
2013-09-04